From a80d451c6ab71f1606d0b5af47e53338d6e2af27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Cs=C3=A1rdi?= Date: Wed, 7 May 2025 13:14:24 +0200 Subject: [PATCH 01/12] Usethis 2025 --- DESCRIPTION | 1 + 1 file changed, 1 insertion(+) diff --git a/DESCRIPTION b/DESCRIPTION index c1f7a8b..180f32d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -43,3 +43,4 @@ Config/testthat/edition: 3 Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.1 +Config/usethis/last-upkeep: 2025-05-07 From 0c4f37c5b886e67432f103a5a6ecb6be6ea79da0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Cs=C3=A1rdi?= Date: Wed, 7 May 2025 13:16:51 +0200 Subject: [PATCH 02/12] usethis::use_air() --- .Rbuildignore | 2 + .vscode/extensions.json | 5 ++ .vscode/settings.json | 6 +++ R/api.R | 1 - R/background.R | 74 ++++++++++++++++--------- R/build.R | 21 +++++--- R/callback.R | 10 ++-- R/compare.R | 12 ++--- R/comparison-summary.R | 21 +++++--- R/comparison.R | 7 +-- R/cran.R | 14 ++--- R/env.R | 46 +++++++++------- R/error.R | 12 ++--- R/http.R | 46 +++++++++------- R/options.R | 1 - R/package.R | 57 ++++++++++++-------- R/parse.R | 92 +++++++++++++++++++------------- R/print.R | 33 ++++++------ R/session-info.R | 44 ++++++++------- R/styles.R | 53 +++++++++--------- R/utils.R | 37 ++++++------- R/xopen.R | 3 +- air.toml | 0 tests/testthat/bad1/R/package.R | 1 - tests/testthat/bad3/R/package.R | 1 - tests/testthat/bad4/R/package.R | 1 - tests/testthat/helpers.R | 12 +++-- tests/testthat/test-auto_clean.R | 1 - tests/testthat/test-build.R | 2 - tests/testthat/test-callback.R | 30 ++++++++--- tests/testthat/test-color.R | 1 - tests/testthat/test-comparison.R | 11 ++-- tests/testthat/test-cran.R | 5 +- tests/testthat/test-crash.R | 8 +-- tests/testthat/test-env.R | 1 - tests/testthat/test-errors.R | 91 +++++++++++++++++++------------ tests/testthat/test-http.R | 32 ++++++----- tests/testthat/test-parse.R | 1 - tests/testthat/test-rcmdcheck.R | 35 ++++++------ tests/testthat/test-tests.R | 2 - tests/testthat/test-utils.R | 1 - 41 files changed, 484 insertions(+), 349 deletions(-) create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json create mode 100644 air.toml diff --git a/.Rbuildignore b/.Rbuildignore index 960003c..0e915a1 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -14,3 +14,5 @@ ^dev-lib$ ^LICENSE\.md$ ^codecov\.yml$ +^[\.]?air\.toml$ +^\.vscode$ diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..344f76e --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "Posit.air-vscode" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f2d0b79 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "[r]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "Posit.air-vscode" + } +} diff --git a/R/api.R b/R/api.R index 7d65635..0357b22 100644 --- a/R/api.R +++ b/R/api.R @@ -1,4 +1,3 @@ - #' Query R CMD check results and parameters #' #' @param check A check result. diff --git a/R/background.R b/R/background.R index b8d9976..a9372ba 100644 --- a/R/background.R +++ b/R/background.R @@ -1,4 +1,3 @@ - #' Run an `R CMD check` process in the background #' #' rcmdcheck_process is an R6 class, that extends the @@ -60,15 +59,29 @@ rcmdcheck_process <- R6Class( inherit = callr::rcmd_process, public = list( - - initialize = function(path = ".", args = character(), - build_args = character(), check_dir = NULL, libpath = .libPaths(), - repos = getOption("repos"), env = character()) - rcc_init(self, private, super, path, args, build_args, check_dir, - libpath, repos, env), - - parse_results = function() - rcc_parse_results(self, private), + initialize = function( + path = ".", + args = character(), + build_args = character(), + check_dir = NULL, + libpath = .libPaths(), + repos = getOption("repos"), + env = character() + ) + rcc_init( + self, + private, + super, + path, + args, + build_args, + check_dir, + libpath, + repos, + env + ), + + parse_results = function() rcc_parse_results(self, private), read_output_lines = function(...) { l <- super$read_output_lines(...) @@ -86,10 +99,9 @@ rcmdcheck_process <- R6Class( private$killed <- TRUE super$kill(...) } - ), private = list( - path = NULL, + path = NULL, check_dir = NULL, targz = NULL, description = NULL, @@ -104,9 +116,18 @@ rcmdcheck_process <- R6Class( #' @importFrom callr rcmd_process rcmd_process_options #' @importFrom desc desc -rcc_init <- function(self, private, super, path, args, build_args, - check_dir, libpath, repos, env) { - +rcc_init <- function( + self, + private, + super, + path, + args, + build_args, + check_dir, + libpath, + repos, + env +) { if (file.info(path)$isdir) { path <- find_package_root_file(path = path) } else { @@ -126,8 +147,13 @@ rcc_init <- function(self, private, super, path, args, build_args, pkgbuild::without_cache(pkgbuild::local_build_tools()) - targz <- build_package(path, check_dir, build_args = build_args, - libpath = libpath, quiet = TRUE) + targz <- build_package( + path, + check_dir, + build_args = build_args, + libpath = libpath, + quiet = TRUE + ) private$description <- desc(path) private$path <- path @@ -146,7 +172,7 @@ rcc_init <- function(self, private, super, path, args, build_args, # probably inside test cases of some package if (Sys.getenv("R_TESTS", "") == "") { private$session_output <- tempfile() - private$tempfiles <- c(private$session_output, profile) + private$tempfiles <- c(private$session_output, profile) profile <- make_fake_profile(package, private$session_output, libdir) chkenv["R_TESTS"] <- profile } @@ -182,12 +208,12 @@ rcc_parse_results <- function(self, private) { on.exit(unlink(private$tempfiles, recursive = TRUE), add = TRUE) new_rcmdcheck( - stdout = paste(win2unix(private$cstdout), collapse = ""), - stderr = paste(win2unix(private$cstderr), collapse = ""), - description = private$description, - status = self$get_exit_status(), - duration = duration(self$get_start_time()), - timeout = private$killed, + stdout = paste(win2unix(private$cstdout), collapse = ""), + stderr = paste(win2unix(private$cstderr), collapse = ""), + description = private$description, + status = self$get_exit_status(), + duration = duration(self$get_start_time()), + timeout = private$killed, session_info = private$session_output ) } diff --git a/R/build.R b/R/build.R index 630ed86..5de414d 100644 --- a/R/build.R +++ b/R/build.R @@ -1,4 +1,3 @@ - #' @importFrom pkgbuild pkgbuild_process #' @importFrom withr with_envvar @@ -17,7 +16,8 @@ build_package <- function(path, tmpdir, build_args, libpath, quiet) { clean_doc <- as_flag(desc$get("Config/build/clean-inst-doc"), NULL) with_envvar( - c("R_LIBS_USER" = paste(libpath, collapse = .Platform$path.sep)), { + c("R_LIBS_USER" = paste(libpath, collapse = .Platform$path.sep)), + { proc <- pkgbuild_process$new( path, tmpdir, @@ -28,15 +28,21 @@ build_package <- function(path, tmpdir, build_args, libpath, quiet) { on.exit(proc$kill(), add = TRUE) callback <- detect_callback() - while (proc$is_incomplete_output() || - proc$is_incomplete_error() - || proc$is_alive()) { + while ( + proc$is_incomplete_output() || + proc$is_incomplete_error() || + proc$is_alive() + ) { proc$poll_io(-1) out <- proc$read_output() err <- proc$read_error() if (!quiet) { - out <- sub("(checking for file .)/.*DESCRIPTION(.)", - "\\1.../DESCRIPTION\\2", out, perl = TRUE) + out <- sub( + "(checking for file .)/.*DESCRIPTION(.)", + "\\1.../DESCRIPTION\\2", + out, + perl = TRUE + ) callback(out) callback(err) } @@ -44,7 +50,6 @@ build_package <- function(path, tmpdir, build_args, libpath, quiet) { proc$get_built_file() } ) - } else { dest <- file.path(tmpdir, basename(path)) if (!file.exists(dest) || normalizePath(dest) != path) { diff --git a/R/callback.R b/R/callback.R index 51dbeb4..79d0711 100644 --- a/R/callback.R +++ b/R/callback.R @@ -1,4 +1,3 @@ - ## This is the callback called for each line of the output ## We color it a bit, OK is green, NOTE is blue ## WARNING is magenta, ERROR is red. @@ -8,10 +7,10 @@ #' @importFrom prettyunits pretty_dt block_callback <- function( - top_line = TRUE, - sys_time = NULL, - as_cran = NA) { - + top_line = TRUE, + sys_time = NULL, + as_cran = NA +) { sys_time <- sys_time %||% Sys.time partial_line <- "" @@ -49,7 +48,6 @@ block_callback <- function( } do_line <- function(x) { - should_time <<- FALSE now <<- sys_time() diff --git a/R/compare.R b/R/compare.R index b7a221d..700e117 100644 --- a/R/compare.R +++ b/R/compare.R @@ -1,4 +1,3 @@ - #' Compare a set of check results to another check result #' #' @param old A check result, or a list of check results. @@ -9,8 +8,8 @@ #' * `status`: comparison status, see below, #' * `old`: list of `rcmdcheck` objects the old check(s), #' * `new`: `rcmdcheck` object, the new check, -#' * `cmp`: -#' +#' * `cmp`: +#' #' #' @family check comparisons #' @export @@ -36,10 +35,11 @@ compare_check_files <- function(old, new) { #' @family check comparisons #' @export -compare_to_cran <- function(check, - flavours = cran_check_flavours(check$package)) { +compare_to_cran <- function( + check, + flavours = cran_check_flavours(check$package) +) { pkg <- check$package cran <- cran_check_results(pkg, flavours = flavours) compare_checks(old = cran, new = check) } - diff --git a/R/comparison-summary.R b/R/comparison-summary.R index 919251b..32ef21f 100644 --- a/R/comparison-summary.R +++ b/R/comparison-summary.R @@ -1,4 +1,3 @@ - #' @export summary.rcmdcheck_comparison <- function(object, ...) { @@ -10,7 +9,8 @@ summary.rcmdcheck_comparison <- function(object, ...) { print.rcmdcheck_comparison_summary <- function(x, ...) { object <- x[[1]] - sum_status <- switch(object$status, + sum_status <- switch( + object$status, "t-" = white(bgRed("T")), "t+" = "T", "i-" = white(bgRed("I")), @@ -25,10 +25,15 @@ print.rcmdcheck_comparison_summary <- function(x, ...) { header <- paste0(sum_status, " ", object$package, " ", vers) cat_line( - col_align(header, width = 40), " ", - symbol$line, symbol$line, " ", - change_summary(object$cmp, "error"), " | ", - change_summary(object$cmp, "warning"), " | ", + col_align(header, width = 40), + " ", + symbol$line, + symbol$line, + " ", + change_summary(object$cmp, "error"), + " | ", + change_summary(object$cmp, "warning"), + " | ", change_summary(object$cmp, "note"), style = darkgrey ) @@ -41,10 +46,10 @@ change_summary <- function(rows, type) { n <- function(change) sum(rows$change == change) paste0( - toupper(substr(type, 1, 1)), ": ", + toupper(substr(type, 1, 1)), + ": ", n(0), if (n(-1)) green(paste0("-", n(-1))) else " ", if (n(1)) red(paste0("+", n(1))) else " " ) } - diff --git a/R/comparison.R b/R/comparison.R index 6f1fe42..489835f 100644 --- a/R/comparison.R +++ b/R/comparison.R @@ -8,7 +8,7 @@ rcmdcheck_comparison <- function(old, new) { # For each problem, determine whether it's new (1), fixed (-1), or # unchanged (0/0.5). - new_df$change <- ifelse(new_df$hash %in% old_df$hash, 0, 1) + new_df$change <- ifelse(new_df$hash %in% old_df$hash, 0, 1) old_df$change <- ifelse(old_df$hash %in% new_df$hash, 0.5, -1) cmp_df <- rbind(old_df, new_df) @@ -21,7 +21,7 @@ rcmdcheck_comparison <- function(old, new) { } else if (inst_fail_new) { ## install still fails status <- "i+" - } else if (new$timeout && ! any(old_df$timeout)) { + } else if (new$timeout && !any(old_df$timeout)) { ## install/check newly timeouts status <- "t-" } else if (new$timeout) { @@ -75,7 +75,8 @@ print.rcmdcheck_comparison <- function(x, header = TRUE, ...) { ) } - status <- switch(x$status, + status <- switch( + x$status, "+" = green("OK"), "-" = red("BROKEN"), "i-" = red("INSTALL FAILURE"), diff --git a/R/cran.R b/R/cran.R index 3204bb0..f0623e4 100644 --- a/R/cran.R +++ b/R/cran.R @@ -1,4 +1,3 @@ - #' Download and show all CRAN check flavour platforms #' #' If the `package` argument is `NULL`, then all current @@ -17,7 +16,6 @@ #' } cran_check_flavours <- function(package = NULL) { - if (is.null(package)) return(cran_check_flavours_generic()) base <- Sys.getenv( @@ -31,7 +29,8 @@ cran_check_flavours <- function(package = NULL) { fl_rows <- grep( " export\\s+)?", # export, if given - "(?[^=]+)", # variable name - "=", # equals sign - "(?['\"]?)", # quote if present - "(?.*)", # value - "\\g{q}", # the same quote again - "\\s*", # trailing whitespace - "$" # end of line + "(?[^=]+)", # variable name + "=", # equals sign + "(?['\"]?)", # quote if present + "(?.*)", # value + "\\g{q}", # the same quote again + "\\s*", # trailing whitespace + "$" # end of line ) parse_dot_line <- function(line) { diff --git a/R/error.R b/R/error.R index 0732322..df356be 100644 --- a/R/error.R +++ b/R/error.R @@ -1,20 +1,20 @@ - report_system_error <- function(msg, status) { - if (status$status == 0) return() if (status$stderr == "") { stop( - msg, ", unknown error, standard output:\n", + msg, + ", unknown error, standard output:\n", yellow(status$stdout), call. = FALSE ) - } else { stop( underline(yellow(paste0("\n", msg, ", standard output:\n\n"))), - yellow(status$stdout), "\n", - underline(red("Standard error:\n\n")), red(status$stderr), + yellow(status$stdout), + "\n", + underline(red("Standard error:\n\n")), + red(status$stderr), call. = FALSE ) } diff --git a/R/http.R b/R/http.R index af69a0a..a391131 100644 --- a/R/http.R +++ b/R/http.R @@ -1,14 +1,14 @@ - #' @importFrom curl new_pool new_handle handle_setopt multi_add multi_run #' @importFrom cli cli_progress_bar cli_progress_update -download_files <- function(urls, - destfiles, - quiet = FALSE, - total_con = 100L, - host_con = 15L, - handles = NULL) { - +download_files <- function( + urls, + destfiles, + quiet = FALSE, + total_con = 100L, + host_con = 15L, + handles = NULL +) { stopifnot( is.character(urls) && !anyNA(urls), is.character(destfiles) & !anyNA(destfiles), @@ -79,11 +79,10 @@ download_files <- function(urls, ) }) - if (getRversion() < "3.6.0") suspendInterrupts <- identity repeat { - if (todo == 0) break; + if (todo == 0) break suspendInterrupts( multi_run(0.1, poll = TRUE, pool = pool) ) @@ -134,12 +133,18 @@ http_error <- function(resp, call = sys.call(-1)) { reason <- http_status(status)$reason message <- sprintf("%s (HTTP %d).", reason, status) status_type <- (status %/% 100) * 100 - if (length(resp[["content"]]) == 0 && !is.null(resp$file) && - file.exists(resp$file)) { - tryCatch({ - n <- file.info(resp$file, extra_cols = FALSE)$size - resp$content <- readBin(resp$file, what = raw(), n = n) - }, error = identity) + if ( + length(resp[["content"]]) == 0 && + !is.null(resp$file) && + file.exists(resp$file) + ) { + tryCatch( + { + n <- file.info(resp$file, extra_cols = FALSE)$size + resp$content <- readBin(resp$file, what = raw(), n = n) + }, + error = identity + ) } http_class <- paste0("http_", unique(c(status, status_type, "error"))) structure( @@ -154,8 +159,13 @@ http_status <- function(status) { stop("Unknown http status code: ", status, call. = FALSE) } - status_types <- c("Information", "Success", "Redirection", "Client error", - "Server error") + status_types <- c( + "Information", + "Success", + "Redirection", + "Client error", + "Server error" + ) status_type <- status_types[[status %/% 100]] # create the final information message diff --git a/R/options.R b/R/options.R index ac337e5..b6909c9 100644 --- a/R/options.R +++ b/R/options.R @@ -1,4 +1,3 @@ - #' rcmdcheck configuration #' #' Options take precedence over environment variables. E.g. if both diff --git a/R/package.R b/R/package.R index 3e01892..6a6c43e 100644 --- a/R/package.R +++ b/R/package.R @@ -1,4 +1,3 @@ - #' Run R CMD check from R and Capture Results #' #' Run R CMD check from R programmatically, and capture the results of the @@ -114,20 +113,20 @@ NULL #' @importFrom desc desc rcmdcheck <- function( - path = ".", - quiet = FALSE, - args = character(), - build_args = character(), - check_dir = NULL, - libpath = .libPaths(), - repos = getOption("repos"), - timeout = Inf, - error_on = Sys.getenv( - "RCMDCHECK_ERROR_ON", - c("never", "error", "warning", "note")[1] - ), - env = character()) { - + path = ".", + quiet = FALSE, + args = character(), + build_args = character(), + check_dir = NULL, + libpath = .libPaths(), + repos = getOption("repos"), + timeout = Inf, + error_on = Sys.getenv( + "RCMDCHECK_ERROR_ON", + c("never", "error", "warning", "note")[1] + ), + env = character() +) { error_on <- match.arg(error_on, c("never", "error", "warning", "note")) if (file.info(path)$isdir) { @@ -148,8 +147,13 @@ rcmdcheck <- function( pkgbuild::without_cache(pkgbuild::local_build_tools()) - targz <- build_package(path, check_dir, build_args = build_args, - libpath = libpath, quiet = quiet) + targz <- build_package( + path, + check_dir, + build_args = build_args, + libpath = libpath, + quiet = quiet + ) start_time <- Sys.time() desc <- desc(targz) @@ -157,7 +161,8 @@ rcmdcheck <- function( out <- with_dir( dirname(targz), - do_check(targz, + do_check( + targz, package = desc$get("Package")[[1]], args = args, libpath = libpath, @@ -192,9 +197,16 @@ rcmdcheck <- function( #' @importFrom withr with_envvar -do_check <- function(targz, package, args, libpath, repos, - quiet, timeout, env) { - +do_check <- function( + targz, + package, + args, + libpath, + repos, + quiet, + timeout, + env +) { # if the pkg.Rcheck directory already exists, unlink it unlink(paste0(package, ".Rcheck"), recursive = TRUE) @@ -242,7 +254,8 @@ do_check <- function(targz, package, args, libpath, repos, if (res$status != 0 && res$status != 1) { stop( call. = FALSE, - "R CMD check process failed with exit status ", res$status, + "R CMD check process failed with exit status ", + res$status, "\n\nStandard output and error:\n", res$stdout ) diff --git a/R/parse.R b/R/parse.R index 9c3fe94..415f802 100644 --- a/R/parse.R +++ b/R/parse.R @@ -1,13 +1,13 @@ - -new_rcmdcheck <- function(stdout, - stderr, - description, - status = 0L, - duration = 0L, - timeout = FALSE, - test_fail = NULL, - session_info = NULL) { - +new_rcmdcheck <- function( + stdout, + stderr, + description, + status = 0L, + duration = 0L, + timeout = FALSE, + test_fail = NULL, + session_info = NULL +) { stopifnot(inherits(description, "description")) # Make sure we don't have \r on windows @@ -21,25 +21,25 @@ new_rcmdcheck <- function(stdout, res <- structure( list( - stdout = stdout, - stderr = stderr, - status = status, - duration = duration, - timeout = timeout, - - rversion = parse_rversion(entries), - platform = parse_platform(entries), - errors = notdone(grep("ERROR\n", entries, value = TRUE)), - warnings = notdone(grep("WARNING\n", entries, value = TRUE)), - notes = notdone(grep("NOTE\n", entries, value = TRUE)), + stdout = stdout, + stderr = stderr, + status = status, + duration = duration, + timeout = timeout, + + rversion = parse_rversion(entries), + platform = parse_platform(entries), + errors = notdone(grep("ERROR\n", entries, value = TRUE)), + warnings = notdone(grep("WARNING\n", entries, value = TRUE)), + notes = notdone(grep("NOTE\n", entries, value = TRUE)), description = description$str(normalize = FALSE), - package = description$get("Package")[[1]], - version = description$get("Version")[[1]], - cran = description$get_field("Repository", "") == "CRAN", - bioc = description$has_fields("biocViews"), + package = description$get("Package")[[1]], + version = description$get("Version")[[1]], + cran = description$get_field("Repository", "") == "CRAN", + bioc = description$has_fields("biocViews"), - checkdir = checkdir, + checkdir = checkdir, test_fail = test_fail %||% get_test_fail(checkdir), test_output = get_test_output(checkdir, pattern = "\\.Rout"), install_out = get_install_out(checkdir) @@ -71,7 +71,15 @@ parse_checkdir <- function(entries) { line <- grep("^using log directory", entries, value = TRUE) sub( - paste0("^using log directory [", quotes, "]([^", quotes, "]+)[", quotes, "]$"), + paste0( + "^using log directory [", + quotes, + "]([^", + quotes, + "]+)[", + quotes, + "]$" + ), "\\1", line, perl = TRUE @@ -89,7 +97,8 @@ get_test_output <- function(path, pattern, encoding = "") { rel_paths <- ifelse( test_dirs == "tests", basename(paths), - paste0(basename(paths), " (", sub("^tests_", "", test_dirs), ")")) + paste0(basename(paths), " (", sub("^tests_", "", test_dirs), ")") + ) names(paths) <- gsub(pattern, "", rel_paths, useBytes = TRUE) trim_header <- function(x) { @@ -103,12 +112,13 @@ get_test_output <- function(path, pattern, encoding = "") { } #' @export -as.data.frame.rcmdcheck <- function(x, - row.names = NULL, - optional = FALSE, - ..., - which) { - +as.data.frame.rcmdcheck <- function( + x, + row.names = NULL, + optional = FALSE, + ..., + which +) { entries <- list( type = c( rep("error", length(x$errors)), @@ -160,7 +170,6 @@ hash_check <- function(check) { #' @importFrom desc description parse_check <- function(file = NULL, text = NULL, ...) { - ## If no text, then find the file, and read it in if (is.null(text)) { file <- find_check_file(file) @@ -195,8 +204,16 @@ validEnc <- function(x) { } reencode_log <- function(log) { - csline <- head(grep("^\\* using session charset: ", - log, perl = TRUE, useBytes = TRUE, value = TRUE), 1) + csline <- head( + grep( + "^\\* using session charset: ", + log, + perl = TRUE, + useBytes = TRUE, + value = TRUE + ), + 1 + ) if (length(csline)) { cs <- strsplit(csline, ": ")[[1]][2] log <- iconv(log, cs, "UTF-8", sub = "byte") @@ -245,7 +262,6 @@ parse_check_url <- function(url, quiet = FALSE) { } find_check_file <- function(file) { - if (is.null(file)) file <- "." if (file.exists(file) && file.info(file)$isdir) { diff --git a/R/print.R b/R/print.R index 9fa4389..fe83acf 100644 --- a/R/print.R +++ b/R/print.R @@ -1,4 +1,3 @@ - #' Print R CMD check results #' @param x Check result object to print. #' @param header Whether to print a header. @@ -10,8 +9,12 @@ #' @importFrom cli symbol #' @importFrom prettyunits pretty_sec -print.rcmdcheck <- function(x, header = TRUE, test_output = getOption("rcmdcheck.test_output", FALSE), ...) { - +print.rcmdcheck <- function( + x, + header = TRUE, + test_output = getOption("rcmdcheck.test_output", FALSE), + ... +) { if (header) { cat_head("R CMD check results", paste(x$package, x$version)) cat_line("Duration: ", pretty_sec(x$duration)) @@ -61,20 +64,17 @@ make_line <- function(x) { paste(rep(symbol$line, x), collapse = "") } -header_line <- function(left = "", right = "", - width = cli::console_width()) { - +header_line <- function(left = "", right = "", width = cli::console_width()) { ncl <- nchar(left) ncr <- nchar(right) if (ncl) left <- paste0(" ", left, " ") if (ncr) right <- paste0(" ", right, " ") - ndashes <- width - ((ncl > 0) * 2 + (ncr > 0) * 2 + ncl + ncr) + ndashes <- width - ((ncl > 0) * 2 + (ncr > 0) * 2 + ncl + ncr) if (ndashes < 4) { right <- substr(right, 1, ncr - (4 - ndashes)) ncr <- nchar(right) - } dashes <- make_line(ndashes) @@ -96,12 +96,18 @@ cat_head <- function(left, right = "", style = cyan) { } print_entry <- function(entry, entry_style) { - lines <- strsplit(entry, "\n", fixed = TRUE)[[1]] - if (grepl(paste0("^(checking tests)|", - "(running tests for arch)|", - "(checking whether package)"), lines[1])) { + if ( + grepl( + paste0( + "^(checking tests)|", + "(running tests for arch)|", + "(checking whether package)" + ), + lines[1] + ) + ) { lines <- c(lines[1], "See below...") } @@ -134,15 +140,12 @@ print.rcmdcheck_summary <- function(x, ..., line = TRUE) { } summary_entry <- function(x, name) { - len <- length(x[[name]]) if (len == 0) { cat(green(paste(len, name, symbol$tick))) - } else if (len == 1) { cat(red(paste(len, sub("s$", "", name), symbol$cross))) - } else { cat(red(paste(len, name, symbol$cross))) } diff --git a/R/session-info.R b/R/session-info.R index 8eb19f4..9703e86 100644 --- a/R/session-info.R +++ b/R/session-info.R @@ -1,5 +1,4 @@ - -make_fake_profile <- function(package, session_output, libdir) { +make_fake_profile <- function(package, session_output, libdir) { profile <- tempfile() args <- list( @@ -8,30 +7,35 @@ make_fake_profile <- function(package, session_output, libdir) { `__libdir__` = libdir ) - expr <- substitute({ - local({ - reg.finalizer( - .GlobalEnv, - function(...) { - tryCatch({ - .libPaths(c(`__libdir__`, .libPaths())) - si <- sessioninfo::session_info(pkgs = `__package__`) - saveRDS(si, `__output__`) - }, error = function(e) NULL) - }, - onexit = TRUE - ) - Sys.unsetenv("R_TESTS") - }) - }, args) + expr <- substitute( + { + local({ + reg.finalizer( + .GlobalEnv, + function(...) { + tryCatch( + { + .libPaths(c(`__libdir__`, .libPaths())) + si <- sessioninfo::session_info(pkgs = `__package__`) + saveRDS(si, `__output__`) + }, + error = function(e) NULL + ) + }, + onexit = TRUE + ) + Sys.unsetenv("R_TESTS") + }) + }, + args + ) cat(deparse(expr), sep = "\n", file = profile) - + profile } get_session_info <- function(package, session_output) { - ## Extract session info for this package session_info <- tryCatch( suppressWarnings(readRDS(session_output)), diff --git a/R/styles.R b/R/styles.R index 5b2bac2..a79bf80 100644 --- a/R/styles.R +++ b/R/styles.R @@ -1,11 +1,10 @@ - rcmdcheck_color <- function(f) { function(...) { num_cols <- as_integer(getOption( "rcmdcheck.num_colors", Sys.getenv("RCMDCHECK_NUM_COLORS", "NA") )) - if (! is.na(num_cols)) { + if (!is.na(num_cols)) { withr::local_options(c(cli.num_colors = num_cols)) } f(...) @@ -15,18 +14,18 @@ rcmdcheck_color <- function(f) { the <- new.env(parent = emptyenv()) style <- function(..., sep = "") { - args <- list(...) st <- names(args) - the$styles <- the$styles %||% list( - "ok" = rcmdcheck_color(cli::col_green), - "note" = rcmdcheck_color(cli::col_blue), - "warn" = rcmdcheck_color(cli::col_magenta), - "err" = rcmdcheck_color(cli::col_red), - "pale" = rcmdcheck_color(cli::col_grey), - "timing" = rcmdcheck_color(cli::col_cyan) - ) + the$styles <- the$styles %||% + list( + "ok" = rcmdcheck_color(cli::col_green), + "note" = rcmdcheck_color(cli::col_blue), + "warn" = rcmdcheck_color(cli::col_magenta), + "err" = rcmdcheck_color(cli::col_red), + "pale" = rcmdcheck_color(cli::col_grey), + "timing" = rcmdcheck_color(cli::col_cyan) + ) nms <- names(args) x <- lapply(seq_along(args), function(i) { @@ -36,24 +35,24 @@ style <- function(..., sep = "") { paste(unlist(x), collapse = sep) } -red <- NULL -green <- NULL -yellow <- NULL -bold <- NULL +red <- NULL +green <- NULL +yellow <- NULL +bold <- NULL underline <- NULL -bgRed <- NULL -white <- NULL -cyan <- NULL -darkgrey <- NULL +bgRed <- NULL +white <- NULL +cyan <- NULL +darkgrey <- NULL .onLoad <- function(libname, pkgname) { - red <<- rcmdcheck_color(cli::col_red) - green <<- rcmdcheck_color(cli::col_green) - yellow <<- rcmdcheck_color(cli::col_yellow) - bold <<- rcmdcheck_color(cli::style_bold) + red <<- rcmdcheck_color(cli::col_red) + green <<- rcmdcheck_color(cli::col_green) + yellow <<- rcmdcheck_color(cli::col_yellow) + bold <<- rcmdcheck_color(cli::style_bold) underline <<- rcmdcheck_color(cli::style_underline) - bgRed <<- rcmdcheck_color(cli::bg_red) - white <<- rcmdcheck_color(cli::col_white) - cyan <<- rcmdcheck_color(cli::col_cyan) - darkgrey <<- rcmdcheck_color(cli::col_grey) + bgRed <<- rcmdcheck_color(cli::bg_red) + white <<- rcmdcheck_color(cli::col_white) + cyan <<- rcmdcheck_color(cli::col_cyan) + darkgrey <<- rcmdcheck_color(cli::col_grey) } diff --git a/R/utils.R b/R/utils.R index 40d19de..23ff4ef 100644 --- a/R/utils.R +++ b/R/utils.R @@ -1,4 +1,3 @@ - read_char <- function(path, encoding = "", ...) { txt <- readChar(path, nchars = file.info(path)$size, useBytes = TRUE, ...) iconv(txt, encoding, "UTF-8", sub = "byte") @@ -17,7 +16,7 @@ is_count <- function(x) { } `%notin%` <- function(needle, haystack) { - ! (needle %in% haystack) + !(needle %in% haystack) } `%||%` <- function(l, r) if (is.null(l)) r else l @@ -67,15 +66,12 @@ data_frame <- function(..., stringsAsFactors = FALSE) { #' @keywords internal myrep <- function(x, len) { - stopifnot(len == 0 || NROW(x) == len || NROW(x) == 1) if (NROW(x) == len) { x - } else if (is.data.frame(x)) { - x[ rep(1, len), ] - + x[rep(1, len), ] } else { rep(x, length.out = len) } @@ -109,23 +105,24 @@ get_install_out <- function(path, encoding = "") { } } -col_align <- function(text, width = cli::console_width(), - align = c("left", "center", "right")) { - +col_align <- function( + text, + width = cli::console_width(), + align = c("left", "center", "right") +) { align <- match.arg(align) nc <- cli::ansi_nchar(text, type = "width") if (width <= nc) { text - } else if (align == "left") { paste0(text, make_space(width - nc)) - } else if (align == "center") { - paste0(make_space(ceiling((width - nc) / 2)), - text, - make_space(floor((width - nc) / 2))) - + paste0( + make_space(ceiling((width - nc) / 2)), + text, + make_space(floor((width - nc) / 2)) + ) } else { paste0(make_space(width - nc), text) } @@ -140,7 +137,9 @@ strrep <- function(x, times) { if (times <= 0L) return("") paste0(replicate(times, x), collapse = "") }, - list(x = x, times = times), MoreArgs = list()) + list(x = x, times = times), + MoreArgs = list() + ) unlist(r, use.names = FALSE) } @@ -165,8 +164,8 @@ as_integer <- function(x) { suppressWarnings(as.integer(x)) } -YES_WORDS <- c("true", "yes", "on", "1", "yep", "yeah") -NO_WORDS <- c("false", "no", "off", "0", "nope", "nah") +YES_WORDS <- c("true", "yes", "on", "1", "yep", "yeah") +NO_WORDS <- c("false", "no", "off", "0", "nope", "nah") as_flag <- function(x, default = FALSE, name = "") { x1 <- trimws(tolower(x)) @@ -193,10 +192,8 @@ should_use_rs_pandoc <- function() { if (tolower(ev) == "true") { TRUE - } else if (tolower(ev) == "false") { FALSE - } else { !nzchar(Sys.which("pandoc")) && nzchar(Sys.getenv("RSTUDIO_PANDOC")) } diff --git a/R/xopen.R b/R/xopen.R index 3446d43..da44582 100644 --- a/R/xopen.R +++ b/R/xopen.R @@ -1,9 +1,8 @@ - #' Open the check directory in a file browser window #' #' @param target `rcmdcheck()` result. #' @inheritParams xopen::xopen -#' +#' #' @export #' @importFrom xopen xopen diff --git a/air.toml b/air.toml new file mode 100644 index 0000000..e69de29 diff --git a/tests/testthat/bad1/R/package.R b/tests/testthat/bad1/R/package.R index fde1c7c..1694b5e 100644 --- a/tests/testthat/bad1/R/package.R +++ b/tests/testthat/bad1/R/package.R @@ -1,4 +1,3 @@ - foobar <- function(argument) { argument } diff --git a/tests/testthat/bad3/R/package.R b/tests/testthat/bad3/R/package.R index 6330baf..903a1f3 100644 --- a/tests/testthat/bad3/R/package.R +++ b/tests/testthat/bad3/R/package.R @@ -1,4 +1,3 @@ - foobar <- function(argument) { argument } diff --git a/tests/testthat/bad4/R/package.R b/tests/testthat/bad4/R/package.R index 5a7cb07..f318ab9 100644 --- a/tests/testthat/bad4/R/package.R +++ b/tests/testthat/bad4/R/package.R @@ -1,4 +1,3 @@ - foobar <- function(argument) { argument } diff --git a/tests/testthat/helpers.R b/tests/testthat/helpers.R index 6556363..e1bdf0b 100644 --- a/tests/testthat/helpers.R +++ b/tests/testthat/helpers.R @@ -1,4 +1,3 @@ - # Wrapper because from edition 3 'class' must be a scalar expect_error_classes <- function(expr, class) { @@ -12,13 +11,20 @@ cran_app <- function() { app <- webfakes::new_app() app$get( list( - webfakes::new_regexp("/nosvn/R.check/(?[-.a-zA-Z0-9_+]+)/(?[-.a-zA-Z0-9_]+)$"), + webfakes::new_regexp( + "/nosvn/R.check/(?[-.a-zA-Z0-9_+]+)/(?[-.a-zA-Z0-9_]+)$" + ), webfakes::new_regexp("/web/checks/(?[-.a-zA-Z0-9_+]+)$") ), function(req, res) { flavour <- req$params$flavour if (is.null(flavour)) flavour <- "" - path <- testthat::test_path("fixtures", "checks", flavour, req$params$name) + path <- testthat::test_path( + "fixtures", + "checks", + flavour, + req$params$name + ) if (file.exists(path)) { res$send_file(path) } else { diff --git a/tests/testthat/test-auto_clean.R b/tests/testthat/test-auto_clean.R index 0e53a7c..4137b12 100644 --- a/tests/testthat/test-auto_clean.R +++ b/tests/testthat/test-auto_clean.R @@ -1,4 +1,3 @@ - test_that("auto_clean deletes files on gc()", { tmp <- tempfile() writeLines("abc", tmp) diff --git a/tests/testthat/test-build.R b/tests/testthat/test-build.R index 585dce1..a114ec2 100644 --- a/tests/testthat/test-build.R +++ b/tests/testthat/test-build.R @@ -1,4 +1,3 @@ - test_that("input targz and targz to check can be the same", { f1 <- tempfile() on.exit(unlink(f1), add = TRUE) @@ -9,7 +8,6 @@ test_that("input targz and targz to check can be the same", { }) test_that("different packages in the same dir are fine", { - dir.create(tmp <- tempfile()) on.exit(unlink(tmp, recursive = TRUE), add = TRUE) diff --git a/tests/testthat/test-callback.R b/tests/testthat/test-callback.R index 212b96d..344916a 100644 --- a/tests/testthat/test-callback.R +++ b/tests/testthat/test-callback.R @@ -1,5 +1,4 @@ - - test_that("block_callback by line", { +test_that("block_callback by line", { withr::local_options(rcmdcheck.timestamp_limit = 1000) chk <- readLines(test_path("fixtures", "test-error.txt")) cb <- block_callback() @@ -16,13 +15,30 @@ test_that("block_callback by chunks", { # We don't make this random, so the partial lines are always the same # and the snapshot does not change pszs <- c( - 1694L, 1751L, 1886L, 1986L, 2476L, 2529L, 2772L, 2832L, 3036L, - 3165L, 3202L, 3389L, 3616L, 3867L, 4304L, 4491L, 4789L, 4818L, - 4993L, 5331L + 1694L, + 1751L, + 1886L, + 1986L, + 2476L, + 2529L, + 2772L, + 2832L, + 3036L, + 3165L, + 3202L, + 3389L, + 3616L, + 3867L, + 4304L, + 4491L, + 4789L, + 4818L, + 4993L, + 5331L ) szs <- c(1, pszs, nchar(chk) + 1L) chunks <- lapply(seq_along(szs)[-1], function(i) { - substr(chk, szs[i-1], szs[i] - 1L) + substr(chk, szs[i - 1], szs[i] - 1L) }) cb <- block_callback() @@ -35,7 +51,7 @@ test_that("block_callback shows running time", { cb <- block_callback() out <- capture.output({ cb("* Doing something") - Sys.sleep(1/2) + Sys.sleep(1 / 2) cb(" ... OK\n") }) expect_match(out[1], "Doing something [(][0-9]+m?s[)]$") diff --git a/tests/testthat/test-color.R b/tests/testthat/test-color.R index 37f0e58..d15a4ec 100644 --- a/tests/testthat/test-color.R +++ b/tests/testthat/test-color.R @@ -1,4 +1,3 @@ - test_that("colors can be turned on and off", { # clean up state withr::local_options(rcmdcheck.num_colors = NULL) diff --git a/tests/testthat/test-comparison.R b/tests/testthat/test-comparison.R index 135be34..c335d63 100644 --- a/tests/testthat/test-comparison.R +++ b/tests/testthat/test-comparison.R @@ -1,12 +1,17 @@ - test_that("basic metadata stored in comparison object", { - cf <- compare_check_files(test_path("REDCapR-ok.log"), test_path("REDCapR-fail.log")) + cf <- compare_check_files( + test_path("REDCapR-ok.log"), + test_path("REDCapR-fail.log") + ) expect_equal(cf$package, "REDCapR") expect_equal(cf$versions, c("0.9.8", "0.9.8")) }) test_that("status correctly computed when both checks are ok", { - cf <- compare_check_files(test_path("minimal-ok.log"), test_path("minimal-ok.log")) + cf <- compare_check_files( + test_path("minimal-ok.log"), + test_path("minimal-ok.log") + ) expect_equal(cf$status, "+") }) diff --git a/tests/testthat/test-cran.R b/tests/testthat/test-cran.R index a5d0046..cba47be 100644 --- a/tests/testthat/test-cran.R +++ b/tests/testthat/test-cran.R @@ -1,4 +1,3 @@ - cran <- webfakes::new_app_process(cran_app()) withr::local_envvar( RCMDCHECK_BASE_URL = paste0(cran$url(), "web/checks/"), @@ -15,11 +14,11 @@ test_that("can get results (windows)", { test_that("can get UTF-8 results", { skip_on_cran() xx <- cran_check_results("rcmdcheck", "r-devel-linux-x86_64-debian-gcc") - expect_s3_class(xx[[1]], "rcmdcheck") + expect_s3_class(xx[[1]], "rcmdcheck") }) test_that("can get ISO-8859-15 results", { skip_on_cran() xx <- cran_check_results("rcmdcheck", "r-devel-linux-x86_64-debian-clang") - expect_s3_class(xx[[1]], "rcmdcheck") + expect_s3_class(xx[[1]], "rcmdcheck") }) diff --git a/tests/testthat/test-crash.R b/tests/testthat/test-crash.R index 35a06e6..5168476 100644 --- a/tests/testthat/test-crash.R +++ b/tests/testthat/test-crash.R @@ -1,4 +1,3 @@ - if (!isTRUE(as.logical(Sys.getenv("RCMDCHECK_EXTRA_TESTS")))) return() test_that("check process crashes", { @@ -21,7 +20,8 @@ test_that("check process crashes", { on.exit(unlink(c(pidfile, dbgfile)), add = TRUE) code <- sprintf( "if (! file.exists('%s')) cat(Sys.getpid(), '\\n', file = '%s')\n", - encodeString(pidfile), encodeString(pidfile) + encodeString(pidfile), + encodeString(pidfile) ) cat(code, file = dbgfile) @@ -33,7 +33,7 @@ test_that("check process crashes", { # Wait until the check is running limit <- Sys.time() + as.difftime(10, units = "secs") - while (! file.exists(pidfile) && Sys.time() < limit) Sys.sleep(0.1) + while (!file.exists(pidfile) && Sys.time() < limit) Sys.sleep(0.1) expect_true(Sys.time() < limit) if (!file.exists(pidfile)) return() @@ -42,7 +42,7 @@ test_that("check process crashes", { tryCatch(as.integer(readLines(pidfile)), error = function(e) NULL) } limit <- Sys.time() + as.difftime(1, units = "secs") - while(!is.integer(pid <- get_pid()) && Sys.time() < limit) Sys.sleep(0.1) + while (!is.integer(pid <- get_pid()) && Sys.time() < limit) Sys.sleep(0.1) expect_true(Sys.time() < limit) if (is.null(pid)) return() diff --git a/tests/testthat/test-env.R b/tests/testthat/test-env.R index a0acdb8..972ac2b 100644 --- a/tests/testthat/test-env.R +++ b/tests/testthat/test-env.R @@ -1,4 +1,3 @@ - test_that("set_env", { called <- FALSE local_mocked_bindings(ignore_env = function(...) called <<- TRUE) diff --git a/tests/testthat/test-errors.R b/tests/testthat/test-errors.R index 17eb7ae..9559418 100644 --- a/tests/testthat/test-errors.R +++ b/tests/testthat/test-errors.R @@ -1,8 +1,6 @@ - test_that("error is thrown as needed, with the correct type", { - cle1 <- list() - + err1 <- list(errors = 1) err2 <- list(errors = 1, warnings = 1) err3 <- list(errors = 1, warnings = 2, notes = 3) @@ -16,41 +14,66 @@ test_that("error is thrown as needed, with the correct type", { expect_silent(handle_error_on(cle1, "warning")) expect_silent(handle_error_on(cle1, "error")) - expect_error_classes(capture_output(handle_error_on(err1, "note")), - class = c("rcmdcheck_error", "rcmdcheck_failure")) - expect_error_classes(capture_output(handle_error_on(err1, "warning")), - class = c("rcmdcheck_error", "rcmdcheck_failure")) - expect_error_classes(capture_output(handle_error_on(err1, "error")), - class = c("rcmdcheck_error", "rcmdcheck_failure")) - expect_error_classes(capture_output(handle_error_on(err2, "note")), - class = c("rcmdcheck_error", "rcmdcheck_warning")) - expect_error_classes(capture_output(handle_error_on(err2, "warning")), - class = c("rcmdcheck_error", "rcmdcheck_warning")) - expect_error_classes(capture_output(handle_error_on(err2, "error")), - class = c("rcmdcheck_error", "rcmdcheck_warning")) - expect_error_classes(capture_output(handle_error_on(err3, "note")), - class = c("rcmdcheck_error", "rcmdcheck_warning", - "rcmdcheck_note")) - expect_error_classes(capture_output(handle_error_on(err3, "warning")), - class = c("rcmdcheck_error", "rcmdcheck_warning", - "rcmdcheck_note")) - expect_error_classes(capture_output(handle_error_on(err3, "error")), - class = c("rcmdcheck_error", "rcmdcheck_warning", - "rcmdcheck_note")) + expect_error_classes( + capture_output(handle_error_on(err1, "note")), + class = c("rcmdcheck_error", "rcmdcheck_failure") + ) + expect_error_classes( + capture_output(handle_error_on(err1, "warning")), + class = c("rcmdcheck_error", "rcmdcheck_failure") + ) + expect_error_classes( + capture_output(handle_error_on(err1, "error")), + class = c("rcmdcheck_error", "rcmdcheck_failure") + ) + expect_error_classes( + capture_output(handle_error_on(err2, "note")), + class = c("rcmdcheck_error", "rcmdcheck_warning") + ) + expect_error_classes( + capture_output(handle_error_on(err2, "warning")), + class = c("rcmdcheck_error", "rcmdcheck_warning") + ) + expect_error_classes( + capture_output(handle_error_on(err2, "error")), + class = c("rcmdcheck_error", "rcmdcheck_warning") + ) + expect_error_classes( + capture_output(handle_error_on(err3, "note")), + class = c("rcmdcheck_error", "rcmdcheck_warning", "rcmdcheck_note") + ) + expect_error_classes( + capture_output(handle_error_on(err3, "warning")), + class = c("rcmdcheck_error", "rcmdcheck_warning", "rcmdcheck_note") + ) + expect_error_classes( + capture_output(handle_error_on(err3, "error")), + class = c("rcmdcheck_error", "rcmdcheck_warning", "rcmdcheck_note") + ) - expect_error_classes(capture_output(handle_error_on(wrn1, "note")), - class = "rcmdcheck_warning") - expect_error_classes(capture_output(handle_error_on(wrn1, "warning")), - class = "rcmdcheck_warning") + expect_error_classes( + capture_output(handle_error_on(wrn1, "note")), + class = "rcmdcheck_warning" + ) + expect_error_classes( + capture_output(handle_error_on(wrn1, "warning")), + class = "rcmdcheck_warning" + ) expect_silent(handle_error_on(wrn1, "error")) - expect_error_classes(capture_output(handle_error_on(wrn2, "note")), - class = c("rcmdcheck_warning", "rcmdcheck_note")) - expect_error_classes(capture_output(handle_error_on(wrn2, "warning")), - class = c("rcmdcheck_warning", "rcmdcheck_note")) + expect_error_classes( + capture_output(handle_error_on(wrn2, "note")), + class = c("rcmdcheck_warning", "rcmdcheck_note") + ) + expect_error_classes( + capture_output(handle_error_on(wrn2, "warning")), + class = c("rcmdcheck_warning", "rcmdcheck_note") + ) expect_silent(handle_error_on(wrn2, "error")) - expect_error_classes(capture_output(handle_error_on(nte1, "note")), - class = "rcmdcheck_note") + expect_error_classes( + capture_output(handle_error_on(nte1, "note")), + class = "rcmdcheck_note" + ) expect_silent(handle_error_on(nte1, "warning")) expect_silent(handle_error_on(nte1, "error")) }) diff --git a/tests/testthat/test-http.R b/tests/testthat/test-http.R index 4ff4951..129b6af 100644 --- a/tests/testthat/test-http.R +++ b/tests/testthat/test-http.R @@ -1,4 +1,3 @@ - if (!identical(Sys.getenv("NOT_CRAN"), "true")) return() if (!isTRUE(as.logical(Sys.getenv("EXTRA_TESTS")))) return() if (getRversion() < "3.6.0") return() @@ -7,16 +6,25 @@ httpbin <- webfakes::new_app_process(webfakes::httpbin_app()) torture_me <- function(expr) { out <- tryCatch( - withCallingHandlers({ - p <- callr::r_bg(function(pid, num = 1000) { - Sys.sleep(1) - for (i in 1:num) { - ps::ps_interrupt(ps::ps_handle(pid)) - Sys.sleep(0.01) - } - }, list(pid = Sys.getpid())) - expr - }, interrupt = function(cnd) { cat("int\n") ; invokeRestart("resume") }), + withCallingHandlers( + { + p <- callr::r_bg( + function(pid, num = 1000) { + Sys.sleep(1) + for (i in 1:num) { + ps::ps_interrupt(ps::ps_handle(pid)) + Sys.sleep(0.01) + } + }, + list(pid = Sys.getpid()) + ) + expr + }, + interrupt = function(cnd) { + cat("int\n") + invokeRestart("resume") + } + ), error = function(err) err ) p$kill() @@ -28,7 +36,7 @@ test_that("http interrupts", { dl <- function() { download_files( - httpbin$url("/drip", query = c(duration =5, numbytes = 1000)), + httpbin$url("/drip", query = c(duration = 5, numbytes = 1000)), tmp <- tempfile() ) } diff --git a/tests/testthat/test-parse.R b/tests/testthat/test-parse.R index bf50f7a..26885be 100644 --- a/tests/testthat/test-parse.R +++ b/tests/testthat/test-parse.R @@ -1,4 +1,3 @@ - test_that("can parse basic package information from file", { skip_on_cran() outfile <- "bikedata-ok.log" diff --git a/tests/testthat/test-rcmdcheck.R b/tests/testthat/test-rcmdcheck.R index 838fcf3..b64eb8d 100644 --- a/tests/testthat/test-rcmdcheck.R +++ b/tests/testthat/test-rcmdcheck.R @@ -1,4 +1,3 @@ - # these are set by devtools, and probably by --as-cran as well, # so we unset them here @@ -9,7 +8,6 @@ withr::local_envvar( ) test_that("rcmdcheck works", { - skip_on_cran() Sys.unsetenv("R_TESTS") @@ -23,15 +21,15 @@ test_that("rcmdcheck works", { tmp_out2 <- tempfile(fileext = ".rda") Sys.setenv(RCMDCHECK_OUTPUT = tmp_out1) Sys.setenv(RCMDBUILD_OUTPUT = tmp_out2) - on.exit(unlink(c(tmp_lib, tmp_out1, tmp_out2), recursive = TRUE), - add = TRUE) + on.exit(unlink(c(tmp_lib, tmp_out1, tmp_out2), recursive = TRUE), add = TRUE) on.exit(Sys.unsetenv("RCMDCHECK_OUTPUT"), add = TRUE) on.exit(Sys.unsetenv("RCMDBUILD_OUTPUT"), add = TRUE) bad1 <- rcmdcheck( test_path("bad1"), quiet = TRUE, - libpath = c(tmp_lib, .libPaths())) + libpath = c(tmp_lib, .libPaths()) + ) expect_match(bad1$warnings[1], "Non-standard license specification") @@ -78,7 +76,6 @@ test_that("rcmdcheck works", { }) test_that("background gives same results", { - skip_on_cran() Sys.unsetenv("R_TESTS") @@ -92,14 +89,14 @@ test_that("background gives same results", { tmp_out2 <- tempfile(fileext = ".rda") Sys.setenv(RCMDCHECK_OUTPUT = tmp_out1) Sys.setenv(RCMDBUILD_OUTPUT = tmp_out2) - on.exit(unlink(c(tmp_lib, tmp_out1, tmp_out2), recursive = TRUE), - add = TRUE) + on.exit(unlink(c(tmp_lib, tmp_out1, tmp_out2), recursive = TRUE), add = TRUE) on.exit(Sys.unsetenv("RCMDCHECK_OUTPUT"), add = TRUE) on.exit(Sys.unsetenv("RCMDBUILD_OUTPUT"), add = TRUE) bad1 <- rcmdcheck_process$new( - test_path("bad1"), - libpath = c(tmp_lib, .libPaths())) + test_path("bad1"), + libpath = c(tmp_lib, .libPaths()) + ) # If we read out the output, it'll still save it internally bad1$read_output() bad1$read_all_output_lines() @@ -127,7 +124,6 @@ test_that("background gives same results", { }) test_that("Installation errors", { - skip_on_cran() bad2 <- rcmdcheck(test_path("bad2"), quiet = TRUE) expect_match(bad2$errors[1], "Installation failed") @@ -146,7 +142,6 @@ test_that("Installation errors", { }) test_that("non-quiet mode works", { - skip_on_cran() Sys.unsetenv("R_TESTS") @@ -167,7 +162,6 @@ test_that("non-quiet mode works", { }) test_that("build arguments", { - skip_on_cran() tmp <- tempfile() on.exit(unlink(tmp), add = TRUE) @@ -181,7 +175,6 @@ test_that("build arguments", { }) test_that("check arguments", { - skip_on_cran() tmp <- tempfile() on.exit(unlink(tmp), add = TRUE) @@ -195,14 +188,16 @@ test_that("check arguments", { test_that("check_dir argument", { wd <- NULL - local_mocked_bindings(do_check = function(...) { + local_mocked_bindings(do_check = function(...) { wd <<- getwd() stop("enough") }) tmp <- tempfile(pattern = "foo bar") on.exit(unlink(tmp)) - expect_error(rcmdcheck(test_path("fixtures/badpackage_1.0.0.tar.gz"), - check_dir = tmp)) + expect_error(rcmdcheck( + test_path("fixtures/badpackage_1.0.0.tar.gz"), + check_dir = tmp + )) expect_true(file.exists(tmp)) expect_equal(normalizePath(wd), normalizePath(tmp)) @@ -212,8 +207,10 @@ test_that("check_dir and rcmdcheck_process", { skip_on_cran() tmp <- tempfile(pattern = "foo bar") on.exit(unlink(tmp)) - px <- rcmdcheck_process$new(test_path("fixtures/badpackage_1.0.0.tar.gz"), - check_dir = tmp) + px <- rcmdcheck_process$new( + test_path("fixtures/badpackage_1.0.0.tar.gz"), + check_dir = tmp + ) on.exit(px$kill(), add = TRUE) expect_true(file.exists(tmp)) expect_true("badpackage_1.0.0.tar.gz" %in% dir(tmp)) diff --git a/tests/testthat/test-tests.R b/tests/testthat/test-tests.R index 7c4914f..ce1191f 100644 --- a/tests/testthat/test-tests.R +++ b/tests/testthat/test-tests.R @@ -1,6 +1,4 @@ - test_that("parsing tests for multiple architectures", { - tgz <- test_path("fixtures", "bad-tests.tar.gz") dir.create(tmp <- tempfile()) on.exit(unlink(tmp, recursive = TRUE), add = TRUE) diff --git a/tests/testthat/test-utils.R b/tests/testthat/test-utils.R index 9dfca18..b891f3f 100644 --- a/tests/testthat/test-utils.R +++ b/tests/testthat/test-utils.R @@ -1,4 +1,3 @@ - test_that("as_flag", { expect_true(as_flag("true")) expect_true(as_flag("TRUE")) From 7c2244d735d28fd7b67f04615b923a95e4568e98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Cs=C3=A1rdi?= Date: Wed, 7 May 2025 13:19:03 +0200 Subject: [PATCH 03/12] Add ROR for Posit in DESCRIPTION --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 180f32d..c2dcec6 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -4,7 +4,7 @@ Version: 1.4.0.9000 Authors@R: c( person("Gábor", "Csárdi", , "csardi.gabor@gmail.com", role = c("cre", "aut")), person("Mango Solutions", role = c("cph", "fnd")), - person("Posit Software, PBC", role = c("cph", "fnd")) + person("Posit Software, PBC", role = c("cph", "fnd"), comment = c(ROR = "03wc8by49")) ) Description: Run 'R CMD check' from 'R' and capture the results of the individual checks. Supports running checks in the background, From a0a51d33b92cad394a9ba23c329eb0adcc15591c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Cs=C3=A1rdi?= Date: Wed, 7 May 2025 13:32:34 +0200 Subject: [PATCH 04/12] knitr::convert_chunk_header(type = "yaml") --- README.Rmd | 3 ++- README.md | 46 +++++++++++++++++++++++----------------------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/README.Rmd b/README.Rmd index 07b080f..e71dc71 100644 --- a/README.Rmd +++ b/README.Rmd @@ -8,7 +8,8 @@ output: -```{r, include = FALSE} +```{r} +#| include: false knitr::opts_chunk$set( collapse = TRUE, comment = "#>", diff --git a/README.md b/README.md index 50f3353..a5442ca 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ Run R CMD check from R and Capture Results ================ -- [rcmdcheck](#rcmdcheck) - - [Installation](#installation) - - [Usage](#usage) +- [rcmdcheck](#rcmdcheck) + - [Installation](#installation) + - [Usage](#usage) @@ -65,7 +65,7 @@ library(rcmdcheck) chk <- rcmdcheck("tests/testthat/bad1", quiet = TRUE) chk #> ── R CMD check results ─────────────────────────────────── badpackage 1.0.0 ──── -#> Duration: 9.7s +#> Duration: 12.2s #> #> ❯ checking DESCRIPTION meta-information ... WARNING #> Non-standard license specification: @@ -85,22 +85,22 @@ names(check_details(chk)) #> [11] "cran" "bioc" ``` -- `package`: Package name. -- `version`: Package version number. -- `notes`: Character vector of check `NOTE`s. -- `warnings`: Character vector of check `WARNING`s. -- `errors`: Character vector of check `ERROR`s. -- `platform`: Platform, e.g. `x86_64-apple-darwin15.6.0`. -- `checkdir`: Check directory. -- `install_out`: Output of the package installation. -- `description`: The text of the `DESCRIPTION` file. -- `session_info`: A `sessioninfo::session_info` object, session - information from within the check process. -- `cran`: Flag, whether this is a CRAN package. (Based on the - `Repository` field in `DESCRIPTION`, which is typically only set for - published CRAN packages.) -- `bioc`: Flag, whether this is a Bioconductor package, based on the - presence of the `biocViews` field in `DESCRIPTION`. +- `package`: Package name. +- `version`: Package version number. +- `notes`: Character vector of check `NOTE`s. +- `warnings`: Character vector of check `WARNING`s. +- `errors`: Character vector of check `ERROR`s. +- `platform`: Platform, e.g. `x86_64-apple-darwin15.6.0`. +- `checkdir`: Check directory. +- `install_out`: Output of the package installation. +- `description`: The text of the `DESCRIPTION` file. +- `session_info`: A `sessioninfo::session_info` object, session + information from within the check process. +- `cran`: Flag, whether this is a CRAN package. (Based on the + `Repository` field in `DESCRIPTION`, which is typically only set for + published CRAN packages.) +- `bioc`: Flag, whether this is a Bioconductor package, based on the + presence of the `biocViews` field in `DESCRIPTION`. Note that if the check results were parsed from a file, some of these fields might be missing (`NULL`), as we don’t have access to the @@ -125,7 +125,7 @@ cran_check_flavours() #> [7] "r-release-linux-x86_64" "r-release-macos-arm64" #> [9] "r-release-macos-x86_64" "r-release-windows-x86_64" #> [11] "r-oldrel-macos-arm64" "r-oldrel-macos-x86_64" -#> [13] "r-oldrel-windows-ix86+x86_64" +#> [13] "r-oldrel-windows-x86_64" ``` `cran_check_results()` loads and parses all check results for a package. @@ -282,14 +282,14 @@ manipulate the check processes. ``` r chkpx <- rcmdcheck_process$new() chkpx -#> PROCESS 'R', running, pid 25919. +#> PROCESS 'R', running, pid 50434. ``` ``` r chkpx$wait() chkpx$parse_results() #> ── R CMD check results ─────────────────────────────── rcmdcheck 1.4.0.9000 ──── -#> Duration: 16.8s +#> Duration: 18.6s #> #> 0 errors ✔ | 0 warnings ✔ | 0 notes ✔ ``` From e3e4859226ae8fe8a953a8ed38b054807fa369ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Cs=C3=A1rdi?= Date: Wed, 7 May 2025 13:36:33 +0200 Subject: [PATCH 05/12] Switch to expect_snapshot(error = TRUE) --- tests/testthat/_snaps/build.md | 8 +++++++ tests/testthat/_snaps/env.md | 8 +++++++ tests/testthat/_snaps/rcmdcheck.md | 38 ++++++++++++++++++++++++++++++ tests/testthat/test-build.R | 5 +--- tests/testthat/test-crash.R | 5 +--- tests/testthat/test-env.R | 2 +- tests/testthat/test-rcmdcheck.R | 22 ++++++++--------- 7 files changed, 68 insertions(+), 20 deletions(-) create mode 100644 tests/testthat/_snaps/build.md create mode 100644 tests/testthat/_snaps/env.md create mode 100644 tests/testthat/_snaps/rcmdcheck.md diff --git a/tests/testthat/_snaps/build.md b/tests/testthat/_snaps/build.md new file mode 100644 index 0000000..7241618 --- /dev/null +++ b/tests/testthat/_snaps/build.md @@ -0,0 +1,8 @@ +# protection against ~ deletion + + Code + check_for_tilde_file(tempfile()) + Condition + Error in `check_for_tilde_file()`: + ! This package contains a file or directory named `~`. Because of a bug in older R versions (before R 4.0.0), building this package might delete your entire home directory!It is best to (carefully!) remove the file. rcmdcheck will exit now. + diff --git a/tests/testthat/_snaps/env.md b/tests/testthat/_snaps/env.md new file mode 100644 index 0000000..480e2f3 --- /dev/null +++ b/tests/testthat/_snaps/env.md @@ -0,0 +1,8 @@ +# load_env_file error + + Code + do() + Condition + Error: + ! Cannot parse check.env: barfoobar + diff --git a/tests/testthat/_snaps/rcmdcheck.md b/tests/testthat/_snaps/rcmdcheck.md new file mode 100644 index 0000000..0999cda --- /dev/null +++ b/tests/testthat/_snaps/rcmdcheck.md @@ -0,0 +1,38 @@ +# background gives same results + + Code + bad1$read_error() + Condition + Error: + ! stderr is not a pipe. + +--- + + Code + bad1$read_all_error_lines() + Condition + Error: + ! stderr is not a pipe. + +# build arguments + + Code + rcmdcheck(test_path("bad1"), build_args = "-v") + Output + -- R CMD build ----------------------------------------------------------------- + R add-on package builder: 4.5.0 (r88135) + Copyright (C) 1997-2025 The R Core Team. + This is free software; see the GNU General Public License version 2 + or later for copying conditions. There is NO warranty. + Condition + Error in `if (!is.null(cmd) && substring(cmd, 1, 1) != "!") ...`: + ! missing value where TRUE/FALSE needed + +# check_dir argument + + Code + rcmdcheck(test_path("fixtures/badpackage_1.0.0.tar.gz"), check_dir = tmp) + Condition + Error in `do_check()`: + ! enough + diff --git a/tests/testthat/test-build.R b/tests/testthat/test-build.R index a114ec2..a975f68 100644 --- a/tests/testthat/test-build.R +++ b/tests/testthat/test-build.R @@ -27,10 +27,7 @@ test_that("different packages in the same dir are fine", { test_that("protection against ~ deletion", { local_mocked_bindings(dir = function(...) c("foo", "~", "bar")) - expect_error( - check_for_tilde_file(tempfile()), - "delete your entire home directory" - ) + expect_snapshot(error = TRUE, check_for_tilde_file(tempfile())) }) test_that("inst/doc can be kept", { diff --git a/tests/testthat/test-crash.R b/tests/testthat/test-crash.R index 5168476..0504d40 100644 --- a/tests/testthat/test-crash.R +++ b/tests/testthat/test-crash.R @@ -60,8 +60,5 @@ test_that("check process crashes", { } # Result of rcmdcheck() - expect_error( - res <- proc$get_result(), - "R CMD check process failed" - ) + expect_snapshot(error = TRUE, proc$get_result()) }) diff --git a/tests/testthat/test-env.R b/tests/testthat/test-env.R index 972ac2b..abfaa27 100644 --- a/tests/testthat/test-env.R +++ b/tests/testthat/test-env.R @@ -97,7 +97,7 @@ test_that("load_env_file error", { load_env_file(envfile) } - expect_error(do(), "Cannot parse check.env") + expect_snapshot(error = TRUE, do()) expect_equal(Sys.getenv("foo"), "notbar") expect_equal(Sys.getenv("bar", ""), "") diff --git a/tests/testthat/test-rcmdcheck.R b/tests/testthat/test-rcmdcheck.R index b64eb8d..3a6fce0 100644 --- a/tests/testthat/test-rcmdcheck.R +++ b/tests/testthat/test-rcmdcheck.R @@ -101,8 +101,8 @@ test_that("background gives same results", { bad1$read_output() bad1$read_all_output_lines() # No separate stderr by default - expect_error(bad1$read_error()) - expect_error(bad1$read_all_error_lines()) + expect_snapshot(error = TRUE, bad1$read_error()) + expect_snapshot(error = TRUE, bad1$read_all_error_lines()) res <- bad1$parse_results() expect_match(res$warnings[1], "Non-standard license specification") @@ -166,12 +166,10 @@ test_that("build arguments", { tmp <- tempfile() on.exit(unlink(tmp), add = TRUE) - out <- capture_output( - o1 <- expect_error( - rcmdcheck(test_path("bad1"), build_args = "-v") - ) + expect_snapshot( + error = TRUE, + rcmdcheck(test_path("bad1"), build_args = "-v") ) - expect_match(out, "R add-on package builder") }) test_that("check arguments", { @@ -194,10 +192,12 @@ test_that("check_dir argument", { }) tmp <- tempfile(pattern = "foo bar") on.exit(unlink(tmp)) - expect_error(rcmdcheck( - test_path("fixtures/badpackage_1.0.0.tar.gz"), - check_dir = tmp - )) + expect_snapshot(error = TRUE, { + rcmdcheck( + test_path("fixtures/badpackage_1.0.0.tar.gz"), + check_dir = tmp + ) + }) expect_true(file.exists(tmp)) expect_equal(normalizePath(wd), normalizePath(tmp)) From d1a4e42619e0b274f047104130bcc2e87a6c66d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Cs=C3=A1rdi?= Date: Wed, 7 May 2025 15:01:49 +0200 Subject: [PATCH 06/12] Fix cran_check_* functions --- NEWS.md | 4 +- R/cran.R | 16 +++--- .../rcmdcheck-00check.txt | 50 +++++++++++-------- .../rcmdcheck-00check.txt | 44 +++++++++------- .../rcmdcheck-00check.txt | 43 +++++++++------- tests/testthat/test-cran.R | 2 +- 6 files changed, 90 insertions(+), 69 deletions(-) rename tests/testthat/fixtures/checks/{r-release-windows-ix86+x86_64 => r-release-windows-x86_64}/rcmdcheck-00check.txt (58%) diff --git a/NEWS.md b/NEWS.md index 7535603..fef4bf9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,6 +6,8 @@ * Update pkgdown template and move url to https://rcmdcheck.r-lib.org. +* `cran_check_results()` works again. + # rcmdcheck 1.4.0 * `cran_check_results()` now downloads results in parallel, so it is @@ -37,7 +39,7 @@ `rcmdcheck.test_output` global option, to control whether to print the full test output or not. (#121) -* RStudio's Pandoc is now on the path during `rcmdcheck()` +* RStudio's Pandoc is now on the path during `rcmdcheck()` and `rcmdcheck_process` (#109, #132, @dpprdan). * `rcmdcheck()` now errors if the check process crashes (#110, #163). diff --git a/R/cran.R b/R/cran.R index f0623e4..72f0f15 100644 --- a/R/cran.R +++ b/R/cran.R @@ -33,12 +33,7 @@ cran_check_flavours <- function(package = NULL) { value = TRUE ) - sub( - "^ \\s*([^\\s<]+)\\s*.*$", - "\\1", - fl_rows, - perl = TRUE - ) + trimws(sub("^.*]+>([^<]+).*$", "\\1", fl_rows)) } cran_check_flavours_generic <- function() { @@ -89,9 +84,16 @@ cran_check_results <- function( download_files(urls, tmp, quiet = quiet) structure( - lapply(tmp, parse_check), + lapply(tmp, parse_check_or_null), names = flavours, package = package, class = "rmcdcheck_cran_results" ) } + +parse_check_or_null <- function(x, ...) { + tryCatch( + parse_check(x, ...), + error = function(e) NULL + ) +} diff --git a/tests/testthat/fixtures/checks/r-devel-linux-x86_64-debian-clang/rcmdcheck-00check.txt b/tests/testthat/fixtures/checks/r-devel-linux-x86_64-debian-clang/rcmdcheck-00check.txt index dbb9bc1..1c584ea 100644 --- a/tests/testthat/fixtures/checks/r-devel-linux-x86_64-debian-clang/rcmdcheck-00check.txt +++ b/tests/testthat/fixtures/checks/r-devel-linux-x86_64-debian-clang/rcmdcheck-00check.txt @@ -1,10 +1,15 @@ -* using log directory '/home/hornik/tmp/R.check/r-devel-clang/Work/PKGS/rcmdcheck.Rcheck' -* using R Under development (unstable) (2021-06-27 r80567) -* using platform: x86_64-pc-linux-gnu (64-bit) -* using session charset: ISO8859-15 -* checking for file 'rcmdcheck/DESCRIPTION' ... OK -* this is package 'rcmdcheck' version '1.3.3' +* using log directory ‘/home/hornik/tmp/R.check/r-devel-clang/Work/PKGS/rcmdcheck.Rcheck’ +* using R Under development (unstable) (2025-05-04 r88189) +* using platform: x86_64-pc-linux-gnu +* R was compiled by + Debian clang version 19.1.7 (3) + Debian flang-new version 19.1.7 (3) +* running under: Debian GNU/Linux trixie/sid +* using session charset: UTF-8 +* checking for file ‘rcmdcheck/DESCRIPTION’ ... OK +* this is package ‘rcmdcheck’ version ‘1.4.0’ * package encoding: UTF-8 +* checking CRAN incoming feasibility ... [1s/2s] OK * checking package namespace information ... OK * checking package dependencies ... OK * checking if this is a source package ... OK @@ -14,7 +19,8 @@ * checking for portable file names ... OK * checking for sufficient/correct file permissions ... OK * checking serialization versions ... OK -* checking whether package 'rcmdcheck' can be installed ... OK +* checking whether package ‘rcmdcheck’ can be installed ... OK +See 'https://www.r-project.org/nosvn/R.check/r-devel-linux-x86_64-debian-clang/rcmdcheck-00install.html' for details. * checking package directory ... OK * checking for future file timestamps ... OK * checking DESCRIPTION meta-information ... OK @@ -22,20 +28,21 @@ * checking for left-over files ... OK * checking index information ... OK * checking package subdirectories ... OK -* checking R files for non-ASCII characters ... OK +* checking code files for non-ASCII characters ... OK * checking R files for syntax errors ... OK -* checking whether the package can be loaded ... OK -* checking whether the package can be loaded with stated dependencies ... OK -* checking whether the package can be unloaded cleanly ... OK -* checking whether the namespace can be loaded with stated dependencies ... OK -* checking whether the namespace can be unloaded cleanly ... OK -* checking loading without being on the library search path ... OK +* checking whether the package can be loaded ... [0s/1s] OK +* checking whether the package can be loaded with stated dependencies ... [0s/0s] OK +* checking whether the package can be unloaded cleanly ... [0s/0s] OK +* checking whether the namespace can be loaded with stated dependencies ... [0s/0s] OK +* checking whether the namespace can be unloaded cleanly ... [0s/1s] OK +* checking loading without being on the library search path ... [1s/1s] OK +* checking whether startup messages can be suppressed ... [0s/1s] OK * checking use of S3 registration ... OK * checking dependencies in R code ... OK * checking S3 generic/method consistency ... OK * checking replacement functions ... OK * checking foreign function calls ... OK -* checking R code for possible problems ... [7s/10s] OK +* checking R code for possible problems ... [7s/9s] OK * checking Rd files ... [0s/0s] OK * checking Rd metadata ... OK * checking Rd line widths ... OK @@ -45,13 +52,12 @@ * checking Rd \usage sections ... OK * checking Rd contents ... OK * checking for unstated dependencies in examples ... OK -* checking LazyData ... NOTE - 'LazyData' is specified without a 'data' directory * checking examples ... [1s/1s] OK -* checking for unstated dependencies in 'tests' ... OK -* checking tests ... [2s/3s] OK - Running 'testthat.R' [2s/3s] -* checking PDF version of manual ... OK +* checking for unstated dependencies in ‘tests’ ... OK +* checking tests ... [11s/13s] OK + Running ‘testthat.R’ [11s/12s] +* checking PDF version of manual ... [4s/6s] OK +* checking HTML version of manual ... [1s/1s] OK * checking for non-standard things in the check directory ... OK * DONE -Status: 1 NOTE +Status: OK diff --git a/tests/testthat/fixtures/checks/r-devel-linux-x86_64-debian-gcc/rcmdcheck-00check.txt b/tests/testthat/fixtures/checks/r-devel-linux-x86_64-debian-gcc/rcmdcheck-00check.txt index f7fa496..4f16668 100644 --- a/tests/testthat/fixtures/checks/r-devel-linux-x86_64-debian-gcc/rcmdcheck-00check.txt +++ b/tests/testthat/fixtures/checks/r-devel-linux-x86_64-debian-gcc/rcmdcheck-00check.txt @@ -1,10 +1,15 @@ * using log directory ‘/home/hornik/tmp/R.check/r-devel-gcc/Work/PKGS/rcmdcheck.Rcheck’ -* using R Under development (unstable) (2021-06-27 r80567) -* using platform: x86_64-pc-linux-gnu (64-bit) +* using R Under development (unstable) (2025-05-04 r88189) +* using platform: x86_64-pc-linux-gnu +* R was compiled by + gcc-14 (Debian 14.2.0-19) 14.2.0 + GNU Fortran (Debian 14.2.0-19) 14.2.0 +* running under: Debian GNU/Linux trixie/sid * using session charset: UTF-8 * checking for file ‘rcmdcheck/DESCRIPTION’ ... OK -* this is package ‘rcmdcheck’ version ‘1.3.3’ +* this is package ‘rcmdcheck’ version ‘1.4.0’ * package encoding: UTF-8 +* checking CRAN incoming feasibility ... [1s/2s] OK * checking package namespace information ... OK * checking package dependencies ... OK * checking if this is a source package ... OK @@ -15,6 +20,7 @@ * checking for sufficient/correct file permissions ... OK * checking serialization versions ... OK * checking whether package ‘rcmdcheck’ can be installed ... OK +See 'https://www.r-project.org/nosvn/R.check/r-devel-linux-x86_64-debian-gcc/rcmdcheck-00install.html' for details. * checking package directory ... OK * checking for future file timestamps ... OK * checking DESCRIPTION meta-information ... OK @@ -22,21 +28,22 @@ * checking for left-over files ... OK * checking index information ... OK * checking package subdirectories ... OK -* checking R files for non-ASCII characters ... OK +* checking code files for non-ASCII characters ... OK * checking R files for syntax errors ... OK -* checking whether the package can be loaded ... OK -* checking whether the package can be loaded with stated dependencies ... OK -* checking whether the package can be unloaded cleanly ... OK -* checking whether the namespace can be loaded with stated dependencies ... OK -* checking whether the namespace can be unloaded cleanly ... OK -* checking loading without being on the library search path ... OK +* checking whether the package can be loaded ... [0s/0s] OK +* checking whether the package can be loaded with stated dependencies ... [0s/0s] OK +* checking whether the package can be unloaded cleanly ... [0s/0s] OK +* checking whether the namespace can be loaded with stated dependencies ... [0s/0s] OK +* checking whether the namespace can be unloaded cleanly ... [0s/1s] OK +* checking loading without being on the library search path ... [0s/1s] OK +* checking whether startup messages can be suppressed ... [0s/1s] OK * checking use of S3 registration ... OK * checking dependencies in R code ... OK * checking S3 generic/method consistency ... OK * checking replacement functions ... OK * checking foreign function calls ... OK -* checking R code for possible problems ... [6s/11s] OK -* checking Rd files ... [0s/1s] OK +* checking R code for possible problems ... [5s/6s] OK +* checking Rd files ... [0s/0s] OK * checking Rd metadata ... OK * checking Rd line widths ... OK * checking Rd cross-references ... OK @@ -45,13 +52,12 @@ * checking Rd \usage sections ... OK * checking Rd contents ... OK * checking for unstated dependencies in examples ... OK -* checking LazyData ... NOTE - 'LazyData' is specified without a 'data' directory -* checking examples ... [1s/1s] OK +* checking examples ... [0s/1s] OK * checking for unstated dependencies in ‘tests’ ... OK -* checking tests ... [2s/3s] OK - Running ‘testthat.R’ [1s/2s] -* checking PDF version of manual ... OK +* checking tests ... [9s/10s] OK + Running ‘testthat.R’ [8s/10s] +* checking PDF version of manual ... [4s/5s] OK +* checking HTML version of manual ... [0s/1s] OK * checking for non-standard things in the check directory ... OK * DONE -Status: 1 NOTE +Status: OK diff --git a/tests/testthat/fixtures/checks/r-release-windows-ix86+x86_64/rcmdcheck-00check.txt b/tests/testthat/fixtures/checks/r-release-windows-x86_64/rcmdcheck-00check.txt similarity index 58% rename from tests/testthat/fixtures/checks/r-release-windows-ix86+x86_64/rcmdcheck-00check.txt rename to tests/testthat/fixtures/checks/r-release-windows-x86_64/rcmdcheck-00check.txt index 66d5d31..3534d8d 100644 --- a/tests/testthat/fixtures/checks/r-release-windows-ix86+x86_64/rcmdcheck-00check.txt +++ b/tests/testthat/fixtures/checks/r-release-windows-x86_64/rcmdcheck-00check.txt @@ -1,9 +1,13 @@ -* using log directory 'd:/Rcompile/CRANpkg/local/4.1/rcmdcheck.Rcheck' -* using R version 4.1.0 (2021-05-18) -* using platform: x86_64-w64-mingw32 (64-bit) -* using session charset: ISO8859-1 +* using log directory 'd:/Rcompile/CRANpkg/local/4.5/rcmdcheck.Rcheck' +* using R version 4.5.0 (2025-04-11 ucrt) +* using platform: x86_64-w64-mingw32 +* R was compiled by + gcc.exe (GCC) 14.2.0 + GNU Fortran (GCC) 14.2.0 +* running under: Windows Server 2022 x64 (build 20348) +* using session charset: UTF-8 * checking for file 'rcmdcheck/DESCRIPTION' ... OK -* this is package 'rcmdcheck' version '1.3.3' +* this is package 'rcmdcheck' version '1.4.0' * package encoding: UTF-8 * checking package namespace information ... OK * checking package dependencies ... OK @@ -12,6 +16,7 @@ * checking for hidden files and directories ... OK * checking for portable file names ... OK * checking whether package 'rcmdcheck' can be installed ... OK +See 'https://www.r-project.org/nosvn/R.check/r-release-windows-x86_64/rcmdcheck-00install.html' for details. * checking installed package size ... OK * checking package directory ... OK * checking DESCRIPTION meta-information ... OK @@ -19,20 +24,21 @@ * checking for left-over files ... OK * checking index information ... OK * checking package subdirectories ... OK -* checking R files for non-ASCII characters ... OK +* checking code files for non-ASCII characters ... OK * checking R files for syntax errors ... OK -* checking whether the package can be loaded ... OK -* checking whether the package can be loaded with stated dependencies ... OK -* checking whether the package can be unloaded cleanly ... OK -* checking whether the namespace can be loaded with stated dependencies ... OK -* checking whether the namespace can be unloaded cleanly ... OK -* checking loading without being on the library search path ... OK +* checking whether the package can be loaded ... [1s] OK +* checking whether the package can be loaded with stated dependencies ... [0s] OK +* checking whether the package can be unloaded cleanly ... [0s] OK +* checking whether the namespace can be loaded with stated dependencies ... [0s] OK +* checking whether the namespace can be unloaded cleanly ... [1s] OK +* checking loading without being on the library search path ... [0s] OK +* checking whether startup messages can be suppressed ... [1s] OK * checking use of S3 registration ... OK * checking dependencies in R code ... OK * checking S3 generic/method consistency ... OK * checking replacement functions ... OK * checking foreign function calls ... OK -* checking R code for possible problems ... [5s] OK +* checking R code for possible problems ... [4s] OK * checking Rd files ... [1s] OK * checking Rd metadata ... OK * checking Rd cross-references ... OK @@ -41,12 +47,11 @@ * checking Rd \usage sections ... OK * checking Rd contents ... OK * checking for unstated dependencies in examples ... OK -* checking LazyData ... NOTE - 'LazyData' is specified without a 'data' directory * checking examples ... [1s] OK * checking for unstated dependencies in 'tests' ... OK -* checking tests ... [3s] OK - Running 'testthat.R' [2s] -* checking PDF version of manual ... OK +* checking tests ... [13s] OK + Running 'testthat.R' [13s] +* checking PDF version of manual ... [20s] OK +* checking HTML version of manual ... [3s] OK * DONE -Status: 1 NOTE +Status: OK diff --git a/tests/testthat/test-cran.R b/tests/testthat/test-cran.R index cba47be..349d017 100644 --- a/tests/testthat/test-cran.R +++ b/tests/testthat/test-cran.R @@ -7,7 +7,7 @@ withr::local_envvar( test_that("can get results (windows)", { skip_on_cran() - xx <- cran_check_results("rcmdcheck", "r-release-windows-ix86+x86_64") + xx <- cran_check_results("rcmdcheck", "r-release-windows-x86_64") expect_s3_class(xx[[1]], "rcmdcheck") }) From aaec69df4035227c08c5b988b4f31d25e0b87ff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Cs=C3=A1rdi?= Date: Wed, 7 May 2025 15:03:04 +0200 Subject: [PATCH 07/12] usethis::use_mit_license() --- LICENSE | 2 +- LICENSE.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index 5047948..3ad7811 100644 --- a/LICENSE +++ b/LICENSE @@ -1,2 +1,2 @@ -YEAR: 2023 +YEAR: 2025 COPYRIGHT HOLDER: rcmdcheck authors diff --git a/LICENSE.md b/LICENSE.md index 35ec960..74d0f88 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ # MIT License -Copyright (c) 2023 rcmdcheck authors +Copyright (c) 2025 rcmdcheck authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 58d4c6e707f02aec6aad620ae7201d0899c76aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Cs=C3=A1rdi?= Date: Wed, 7 May 2025 15:03:19 +0200 Subject: [PATCH 08/12] usethis::use_tidy_description() --- DESCRIPTION | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index c2dcec6..5165f1d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -4,7 +4,8 @@ Version: 1.4.0.9000 Authors@R: c( person("Gábor", "Csárdi", , "csardi.gabor@gmail.com", role = c("cre", "aut")), person("Mango Solutions", role = c("cph", "fnd")), - person("Posit Software, PBC", role = c("cph", "fnd"), comment = c(ROR = "03wc8by49")) + person("Posit Software, PBC", role = c("cph", "fnd"), + comment = c(ROR = "03wc8by49")) ) Description: Run 'R CMD check' from 'R' and capture the results of the individual checks. Supports running checks in the background, @@ -40,7 +41,7 @@ Suggests: webfakes Config/Needs/website: tidyverse/tidytemplate Config/testthat/edition: 3 +Config/usethis/last-upkeep: 2025-05-07 Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.1 -Config/usethis/last-upkeep: 2025-05-07 From 7663822c5c7221e9a9dc8e2098cf186daa1fa9ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Cs=C3=A1rdi?= Date: Wed, 7 May 2025 15:05:41 +0200 Subject: [PATCH 09/12] usethis::use_tidy_github_actions() --- .github/workflows/R-CMD-check.yaml | 1 - .github/workflows/pkgdown.yaml | 1 - .github/workflows/test-coverage.yaml | 11 +- README.Rmd | 4 +- README.md | 235 ++++++++++++++++++--------- 5 files changed, 166 insertions(+), 86 deletions(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 064677b..69cfc6a 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -8,7 +8,6 @@ on: push: branches: [main, master] pull_request: - branches: [main, master] name: R-CMD-check.yaml diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml index 4bbce75..bfc9f4d 100644 --- a/.github/workflows/pkgdown.yaml +++ b/.github/workflows/pkgdown.yaml @@ -4,7 +4,6 @@ on: push: branches: [main, master] pull_request: - branches: [main, master] release: types: [published] workflow_dispatch: diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index 9882260..0ab748d 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -4,7 +4,6 @@ on: push: branches: [main, master] pull_request: - branches: [main, master] name: test-coverage.yaml @@ -35,14 +34,16 @@ jobs: clean = FALSE, install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package") ) + print(cov) covr::to_cobertura(cov) shell: Rscript {0} - - uses: codecov/codecov-action@v4 + - uses: codecov/codecov-action@v5 with: - fail_ci_if_error: ${{ github.event_name != 'pull_request' && true || false }} - file: ./cobertura.xml - plugin: noop + # Fail if error if not on PR, or if on PR and token is given + fail_ci_if_error: ${{ github.event_name != 'pull_request' || secrets.CODECOV_TOKEN }} + files: ./cobertura.xml + plugins: noop disable_search: true token: ${{ secrets.CODECOV_TOKEN }} diff --git a/README.Rmd b/README.Rmd index e71dc71..8a0d01e 100644 --- a/README.Rmd +++ b/README.Rmd @@ -27,7 +27,7 @@ knitr::opts_chunk$set( [![](https://www.r-pkg.org/badges/version/rcmdcheck)](https://www.r-pkg.org/pkg/rcmdcheck) [![CRAN RStudio mirror downloads](https://cranlogs.r-pkg.org/badges/rcmdcheck)](https://www.r-pkg.org/pkg/rcmdcheck) [![R-CMD-check](https://github.com/r-lib/rcmdcheck/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/r-lib/rcmdcheck/actions/workflows/R-CMD-check.yaml) -[![Codecov test coverage](https://codecov.io/gh/r-lib/rcmdcheck/branch/main/graph/badge.svg)](https://app.codecov.io/gh/r-lib/rcmdcheck?branch=main) +[![Codecov test coverage](https://codecov.io/gh/r-lib/rcmdcheck/graph/badge.svg)](https://app.codecov.io/gh/r-lib/rcmdcheck) Run R CMD check from R programmatically and capture the results of the @@ -36,7 +36,7 @@ individual checks. ## Installation Install the released version from CRAN - + ```r install.packages("rcmdcheck") ``` diff --git a/README.md b/README.md index a5442ca..a6c883a 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ Run R CMD check from R and Capture Results ================ -- [rcmdcheck](#rcmdcheck) - - [Installation](#installation) - - [Usage](#usage) +- [rcmdcheck](#rcmdcheck) + - [Installation](#installation) + - [Usage](#usage) @@ -19,7 +19,7 @@ Run R CMD check from R and Capture Results downloads](https://cranlogs.r-pkg.org/badges/rcmdcheck)](https://www.r-pkg.org/pkg/rcmdcheck) [![R-CMD-check](https://github.com/r-lib/rcmdcheck/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/r-lib/rcmdcheck/actions/workflows/R-CMD-check.yaml) [![Codecov test -coverage](https://codecov.io/gh/r-lib/rcmdcheck/branch/main/graph/badge.svg)](https://app.codecov.io/gh/r-lib/rcmdcheck?branch=main) +coverage](https://codecov.io/gh/r-lib/rcmdcheck/graph/badge.svg)](https://app.codecov.io/gh/r-lib/rcmdcheck) Run R CMD check from R programmatically and capture the results of the @@ -65,7 +65,7 @@ library(rcmdcheck) chk <- rcmdcheck("tests/testthat/bad1", quiet = TRUE) chk #> ── R CMD check results ─────────────────────────────────── badpackage 1.0.0 ──── -#> Duration: 12.2s +#> Duration: 12.5s #> #> ❯ checking DESCRIPTION meta-information ... WARNING #> Non-standard license specification: @@ -85,22 +85,22 @@ names(check_details(chk)) #> [11] "cran" "bioc" ``` -- `package`: Package name. -- `version`: Package version number. -- `notes`: Character vector of check `NOTE`s. -- `warnings`: Character vector of check `WARNING`s. -- `errors`: Character vector of check `ERROR`s. -- `platform`: Platform, e.g. `x86_64-apple-darwin15.6.0`. -- `checkdir`: Check directory. -- `install_out`: Output of the package installation. -- `description`: The text of the `DESCRIPTION` file. -- `session_info`: A `sessioninfo::session_info` object, session - information from within the check process. -- `cran`: Flag, whether this is a CRAN package. (Based on the - `Repository` field in `DESCRIPTION`, which is typically only set for - published CRAN packages.) -- `bioc`: Flag, whether this is a Bioconductor package, based on the - presence of the `biocViews` field in `DESCRIPTION`. +- `package`: Package name. +- `version`: Package version number. +- `notes`: Character vector of check `NOTE`s. +- `warnings`: Character vector of check `WARNING`s. +- `errors`: Character vector of check `ERROR`s. +- `platform`: Platform, e.g. `x86_64-apple-darwin15.6.0`. +- `checkdir`: Check directory. +- `install_out`: Output of the package installation. +- `description`: The text of the `DESCRIPTION` file. +- `session_info`: A `sessioninfo::session_info` object, session + information from within the check process. +- `cran`: Flag, whether this is a CRAN package. (Based on the + `Repository` field in `DESCRIPTION`, which is typically only set for + published CRAN packages.) +- `bioc`: Flag, whether this is a Bioconductor package, based on the + presence of the `biocViews` field in `DESCRIPTION`. Note that if the check results were parsed from a file, some of these fields might be missing (`NULL`), as we don’t have access to the @@ -133,123 +133,204 @@ cran_check_flavours() ``` r cran_check_results("igraph") #> $`r-devel-linux-x86_64-debian-clang` -#> ── R CMD check results ─────────────────────────────────────── igraph 1.4.1 ──── +#> ── R CMD check results ─────────────────────────────────────── igraph 2.1.4 ──── #> Duration: 0ms #> -#> 0 errors ✔ | 0 warnings ✔ | 0 notes ✔ +#> ❯ checking compiled code ... NOTE +#> File ‘igraph/libs/igraph.so’: +#> Found non-API call to R: ‘Rf_allocSExp’ +#> +#> Compiled code should not call non-API entry points in R. +#> +#> See ‘Writing portable packages’ in the ‘Writing R Extensions’ manual, +#> and section ‘Moving into C API compliance’ for issues with the use of +#> non-API entry points. +#> +#> 0 errors ✔ | 0 warnings ✔ | 1 note ✖ #> #> $`r-devel-linux-x86_64-debian-gcc` -#> ── R CMD check results ─────────────────────────────────────── igraph 1.4.1 ──── +#> ── R CMD check results ─────────────────────────────────────── igraph 2.1.4 ──── #> Duration: 0ms #> -#> 0 errors ✔ | 0 warnings ✔ | 0 notes ✔ +#> ❯ checking compiled code ... NOTE +#> File ‘igraph/libs/igraph.so’: +#> Found non-API call to R: ‘Rf_allocSExp’ +#> +#> Compiled code should not call non-API entry points in R. +#> +#> See ‘Writing portable packages’ in the ‘Writing R Extensions’ manual, +#> and section ‘Moving into C API compliance’ for issues with the use of +#> non-API entry points. +#> +#> 0 errors ✔ | 0 warnings ✔ | 1 note ✖ #> #> $`r-devel-linux-x86_64-fedora-clang` -#> ── R CMD check results ─────────────────────────────────────── igraph 1.4.1 ──── +#> ── R CMD check results ─────────────────────────────────────── igraph 2.1.4 ──── #> Duration: 0ms #> -#> ❯ checking installed package size ... NOTE -#> installed size is 7.2Mb -#> sub-directories of 1Mb or more: -#> R 1.4Mb -#> help 1.4Mb -#> libs 3.3Mb +#> ❯ checking compiled code ... NOTE +#> File ‘igraph/libs/igraph.so’: +#> Found non-API call to R: ‘Rf_allocSExp’ +#> +#> Compiled code should not call non-API entry points in R. +#> +#> See ‘Writing portable packages’ in the ‘Writing R Extensions’ manual, +#> and section ‘Moving into C API compliance’ for issues with the use of +#> non-API entry points. #> #> 0 errors ✔ | 0 warnings ✔ | 1 note ✖ #> #> $`r-devel-linux-x86_64-fedora-gcc` -#> ── R CMD check results ─────────────────────────────────────── igraph 1.4.1 ──── +#> ── R CMD check results ─────────────────────────────────────── igraph 2.1.4 ──── #> Duration: 0ms #> -#> 0 errors ✔ | 0 warnings ✔ | 0 notes ✔ +#> ❯ checking compiled code ... NOTE +#> File ‘igraph/libs/igraph.so’: +#> Found non-API call to R: ‘Rf_allocSExp’ +#> +#> Compiled code should not call non-API entry points in R. +#> +#> See ‘Writing portable packages’ in the ‘Writing R Extensions’ manual, +#> and section ‘Moving into C API compliance’ for issues with the use of +#> non-API entry points. +#> +#> 0 errors ✔ | 0 warnings ✔ | 1 note ✖ +#> +#> $`r-devel-windows-x86_64` +#> ── R CMD check results ─────────────────────────────────────── igraph 2.1.4 ──── +#> Duration: 0ms +#> +#> ❯ checking compiled code ... NOTE +#> File 'igraph/libs/x64/igraph.dll': +#> Found non-API call to R: 'Rf_allocSExp' +#> +#> Compiled code should not call non-API entry points in R. +#> +#> See 'Writing portable packages' in the 'Writing R Extensions' manual, +#> and section 'Moving into C API compliance' for issues with the use of +#> non-API entry points. +#> +#> 0 errors ✔ | 0 warnings ✔ | 1 note ✖ #> #> $`r-patched-linux-x86_64` -#> ── R CMD check results ─────────────────────────────────────── igraph 1.4.1 ──── +#> ── R CMD check results ─────────────────────────────────────── igraph 2.1.4 ──── #> Duration: 0ms #> -#> 0 errors ✔ | 0 warnings ✔ | 0 notes ✔ +#> ❯ checking compiled code ... NOTE +#> File ‘igraph/libs/igraph.so’: +#> Found non-API call to R: ‘Rf_allocSExp’ +#> +#> Compiled code should not call non-API entry points in R. +#> +#> See ‘Writing portable packages’ in the ‘Writing R Extensions’ manual, +#> and section ‘Moving into C API compliance’ for issues with the use of +#> non-API entry points. +#> +#> 0 errors ✔ | 0 warnings ✔ | 1 note ✖ #> #> $`r-release-linux-x86_64` -#> ── R CMD check results ─────────────────────────────────────── igraph 1.4.1 ──── +#> ── R CMD check results ─────────────────────────────────────── igraph 2.1.4 ──── #> Duration: 0ms #> -#> 0 errors ✔ | 0 warnings ✔ | 0 notes ✔ +#> ❯ checking compiled code ... NOTE +#> File ‘igraph/libs/igraph.so’: +#> Found non-API call to R: ‘Rf_allocSExp’ +#> +#> Compiled code should not call non-API entry points in R. +#> +#> See ‘Writing portable packages’ in the ‘Writing R Extensions’ manual, +#> and section ‘Moving into C API compliance’ for issues with the use of +#> non-API entry points. +#> +#> 0 errors ✔ | 0 warnings ✔ | 1 note ✖ #> #> $`r-release-macos-arm64` -#> ── R CMD check results ─────────────────────────────────────── igraph 1.4.1 ──── +#> ── R CMD check results ─────────────────────────────────────── igraph 2.1.4 ──── #> Duration: 0ms #> -#> ❯ checking installed package size ... NOTE -#> installed size is 19.9Mb -#> sub-directories of 1Mb or more: -#> R 2.1Mb -#> help 1.4Mb -#> libs 15.4Mb +#> ❯ checking compiled code ... NOTE +#> File ‘igraph/libs/igraph.so’: +#> Found non-API call to R: ‘Rf_allocSExp’ +#> +#> Compiled code should not call non-API entry points in R. +#> +#> See ‘Writing portable packages’ in the ‘Writing R Extensions’ manual, +#> and section ‘Moving into C API compliance’ for issues with the use of +#> non-API entry points. #> #> 0 errors ✔ | 0 warnings ✔ | 1 note ✖ #> #> $`r-release-macos-x86_64` -#> ── R CMD check results ─────────────────────────────────────── igraph 1.4.1 ──── +#> ── R CMD check results ─────────────────────────────────────── igraph 2.1.4 ──── #> Duration: 0ms #> -#> ❯ checking installed package size ... NOTE -#> installed size is 18.5Mb -#> sub-directories of 1Mb or more: -#> R 1.4Mb -#> help 1.4Mb -#> libs 14.6Mb +#> ❯ checking compiled code ... NOTE +#> File ‘igraph/libs/igraph.so’: +#> Found non-API call to R: ‘Rf_allocSExp’ +#> +#> Compiled code should not call non-API entry points in R. +#> +#> See ‘Writing portable packages’ in the ‘Writing R Extensions’ manual, +#> and section ‘Moving into C API compliance’ for issues with the use of +#> non-API entry points. #> #> 0 errors ✔ | 0 warnings ✔ | 1 note ✖ #> #> $`r-release-windows-x86_64` -#> ── R CMD check results ─────────────────────────────────────── igraph 1.4.1 ──── +#> ── R CMD check results ─────────────────────────────────────── igraph 2.1.4 ──── #> Duration: 0ms #> -#> ❯ checking installed package size ... NOTE -#> installed size is 10.3Mb -#> sub-directories of 1Mb or more: -#> R 1.4Mb -#> help 1.4Mb -#> libs 6.4Mb +#> ❯ checking compiled code ... NOTE +#> File 'igraph/libs/x64/igraph.dll': +#> Found non-API call to R: 'Rf_allocSExp' +#> +#> Compiled code should not call non-API entry points in R. +#> +#> See 'Writing portable packages' in the 'Writing R Extensions' manual, +#> and section 'Moving into C API compliance' for issues with the use of +#> non-API entry points. #> #> 0 errors ✔ | 0 warnings ✔ | 1 note ✖ #> #> $`r-oldrel-macos-arm64` -#> ── R CMD check results ─────────────────────────────────────── igraph 1.4.1 ──── +#> ── R CMD check results ─────────────────────────────────────── igraph 2.1.4 ──── #> Duration: 0ms #> #> ❯ checking installed package size ... NOTE -#> installed size is 19.9Mb +#> installed size is 23.8Mb #> sub-directories of 1Mb or more: -#> R 2.0Mb -#> help 1.4Mb -#> libs 15.4Mb +#> R 2.1Mb +#> doc 1.2Mb +#> help 2.9Mb +#> libs 17.1Mb #> #> 0 errors ✔ | 0 warnings ✔ | 1 note ✖ #> #> $`r-oldrel-macos-x86_64` -#> ── R CMD check results ─────────────────────────────────────── igraph 1.4.1 ──── +#> ── R CMD check results ─────────────────────────────────────── igraph 2.1.4 ──── #> Duration: 0ms #> #> ❯ checking installed package size ... NOTE -#> installed size is 18.5Mb +#> installed size is 23.6Mb #> sub-directories of 1Mb or more: -#> R 1.4Mb -#> help 1.4Mb -#> libs 14.6Mb +#> R 1.3Mb +#> doc 1.2Mb +#> help 2.0Mb +#> libs 18.7Mb #> #> 0 errors ✔ | 0 warnings ✔ | 1 note ✖ #> -#> $`r-oldrel-windows-ix86+x86_64` -#> ── R CMD check results ─────────────────────────────────────── igraph 1.4.1 ──── +#> $`r-oldrel-windows-x86_64` +#> ── R CMD check results ─────────────────────────────────────── igraph 2.1.4 ──── #> Duration: 0ms #> #> ❯ checking installed package size ... NOTE -#> installed size is 17.2Mb +#> installed size is 10.7Mb #> sub-directories of 1Mb or more: -#> R 1.4Mb -#> help 1.4Mb -#> libs 13.4Mb +#> R 1.3Mb +#> doc 1.2Mb +#> help 2.1Mb +#> libs 5.7Mb #> #> 0 errors ✔ | 0 warnings ✔ | 1 note ✖ #> @@ -282,14 +363,14 @@ manipulate the check processes. ``` r chkpx <- rcmdcheck_process$new() chkpx -#> PROCESS 'R', running, pid 50434. +#> PROCESS 'R', running, pid 74156. ``` ``` r chkpx$wait() chkpx$parse_results() #> ── R CMD check results ─────────────────────────────── rcmdcheck 1.4.0.9000 ──── -#> Duration: 18.6s +#> Duration: 19.5s #> #> 0 errors ✔ | 0 warnings ✔ | 0 notes ✔ ``` From 1405922a5bfe998acea2c5c9fc65aa517a4bbc72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Cs=C3=A1rdi?= Date: Wed, 7 May 2025 15:26:36 +0200 Subject: [PATCH 10/12] GHA: need to install tinytex To avoid the message about the missing pdflatex in the test snapshots. --- .github/workflows/R-CMD-check.yaml | 2 +- .github/workflows/test-coverage.yaml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 69cfc6a..792f694 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -42,8 +42,8 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: r-lib/actions/setup-pandoc@v2 + - uses: r-lib/actions/setup-tinytex@v2 - uses: r-lib/actions/setup-r@v2 with: diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index 0ab748d..93bad67 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -17,6 +17,7 @@ jobs: steps: - uses: actions/checkout@v4 + - uses: r-lib/actions/setup-tinytex@v2 - uses: r-lib/actions/setup-r@v2 with: From bf4c2542d21cbab3d91b0d86cf5aab96d6ab5181 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Cs=C3=A1rdi?= Date: Wed, 7 May 2025 16:01:13 +0200 Subject: [PATCH 11/12] Fix an R version dependent test snapshot --- tests/testthat/_snaps/rcmdcheck.md | 4 ++-- tests/testthat/test-rcmdcheck.R | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/tests/testthat/_snaps/rcmdcheck.md b/tests/testthat/_snaps/rcmdcheck.md index 0999cda..26d7fb9 100644 --- a/tests/testthat/_snaps/rcmdcheck.md +++ b/tests/testthat/_snaps/rcmdcheck.md @@ -20,8 +20,8 @@ rcmdcheck(test_path("bad1"), build_args = "-v") Output -- R CMD build ----------------------------------------------------------------- - R add-on package builder: 4.5.0 (r88135) - Copyright (C) 1997-2025 The R Core Team. + R add-on package builder: (r) + Copyright (C) 1997- The R Core Team. This is free software; see the GNU General Public License version 2 or later for copying conditions. There is NO warranty. Condition diff --git a/tests/testthat/test-rcmdcheck.R b/tests/testthat/test-rcmdcheck.R index 3a6fce0..c776a53 100644 --- a/tests/testthat/test-rcmdcheck.R +++ b/tests/testthat/test-rcmdcheck.R @@ -168,7 +168,16 @@ test_that("build arguments", { expect_snapshot( error = TRUE, - rcmdcheck(test_path("bad1"), build_args = "-v") + rcmdcheck(test_path("bad1"), build_args = "-v"), + transform = function(x) { + x <- sub( + "package builder: [.0-9]+ [(]r[0-9]+[)]", + "package builder: (r)", + x + ) + x <- sub("[(]C[)] 1997-[0-9]+ ", "(C) 1997- ", x) + x + } ) }) From 762906c3d0e4d9deb6b45c9fd53868a0736f595c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Cs=C3=A1rdi?= Date: Wed, 7 May 2025 16:12:54 +0200 Subject: [PATCH 12/12] Add manual trigger to GHA check workflow --- .github/workflows/R-CMD-check.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 792f694..3e8e369 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -8,6 +8,7 @@ on: push: branches: [main, master] pull_request: + workflow_dispatch: name: R-CMD-check.yaml