## ----setup, include = FALSE--------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) library(reproducr) ## ----single-vs-dir, eval = FALSE---------------------------------------------- # # Single file # report <- audit_script("analysis.R") # # # All scripts in a directory (recursive) # report <- audit_script("R/") # # # Whole project # report <- audit_script(".") ## ----version-resolution------------------------------------------------------- script <- tempfile(fileext = ".R") writeLines(c( "x <- dplyr::filter(mtcars, cyl == 4)", "y <- ggplot2::ggplot(x, ggplot2::aes(mpg, wt))" ), script) # renv = FALSE — use installed library (no renv.lock in tempdir) report <- audit_script(script, renv = FALSE, verbose = FALSE) # Version column — NA means the package is not installed report$calls[, c("pkg", "fn", "pkg_version")] ## ----audit-object------------------------------------------------------------- report <- audit_script(script, renv = FALSE, verbose = FALSE) # Environment fingerprint report$env # Files scanned report$paths # Programmatic summary s <- summary(report) s$n_calls s$calls_per_pkg ## ----changelog-check---------------------------------------------------------- # Write a script that calls a function with a known breaking change risky_script <- tempfile(fileext = ".R") writeLines(c( "# dplyr 1.1.0 changed summarise() grouping behaviour", "x <- dplyr::group_by(mtcars, cyl)", "y <- dplyr::summarise(x, mean_mpg = mean(mpg))", "z <- stringr::str_c('a', NA)" # str_c NA-handling changed in 1.5.0 ), risky_script) report <- audit_script(risky_script, renv = FALSE, verbose = FALSE) risks <- risk_score(report, methods = "changelog") print(risks) ## ----seed-check--------------------------------------------------------------- seed_script <- tempfile(fileext = ".R") writeLines(c( "# First call — no seed above it", "x <- stats::rnorm(100)", "", "# Second call — seed present within 50 lines", "set.seed(237)", "y <- stats::rbinom(100, 1, 0.5)", "", "# Third call — seed is there but 60 lines away (beyond the window)", rep("z <- 1", 55), "w <- stats::runif(10)" ), seed_script) report <- audit_script(seed_script, renv = FALSE, verbose = FALSE) risks <- risk_score(report, methods = "seed_check") as.data.frame(risks)[, c("line", "call", "risk", "description")] ## ----locale-check------------------------------------------------------------- locale_script <- tempfile(fileext = ".R") writeLines(c( "x <- base::sort(c('banana', 'apple', 'cherry'))", "y <- base::format(3.14159, digits = 3)", "z <- base::strftime(Sys.time(), '%B')" # month name is locale-dependent ), locale_script) report <- audit_script(locale_script, renv = FALSE, verbose = FALSE) risks <- risk_score(report, methods = "locale_check") as.data.frame(risks)[, c("call", "risk", "description")] ## ----combine-checks----------------------------------------------------------- full_script <- tempfile(fileext = ".R") writeLines(c( "x <- dplyr::summarise(mtcars, n = dplyr::n())", "y <- stats::rnorm(10)", "z <- base::sort(letters)" ), full_script) report <- audit_script(full_script, renv = FALSE, verbose = FALSE) # All checks all_risks <- risk_score(report) # Changelog only changelog_risks <- risk_score(report, methods = "changelog") # Seed and locale only other_risks <- risk_score(report, methods = c("seed_check", "locale_check")) nrow(all_risks) nrow(changelog_risks) nrow(other_risks) ## ----min-risk----------------------------------------------------------------- # Only items worth acting on immediately high_only <- risk_score(report, min_risk = "high") # Medium and above medium_up <- risk_score(report, min_risk = "medium") # Everything (default) all_items <- risk_score(report, min_risk = "low") c(high = nrow(high_only), medium_up = nrow(medium_up), all = nrow(all_items)) ## ----results-as-df------------------------------------------------------------ risks <- risk_score(report) # Standard subsetting risks[risks$check == "seed_check", ] # Count by risk level table(risks$risk) # Convert to plain data.frame (drops the extra class) df <- as.data.frame(risks) class(df) ## ----results-pipe, eval = FALSE----------------------------------------------- # library(dplyr) # # risk_score(report) |> # filter(risk == "high") |> # select(call, line, description) |> # arrange(line) ## ----cleanup, include = FALSE------------------------------------------------- unlink(c(script, risky_script, seed_script, locale_script, full_script))