## ----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))

