diff --git a/.github/skills/create-issue/SKILL.md b/.github/skills/create-issue/SKILL.md index e9fb310..be8fc8b 100644 --- a/.github/skills/create-issue/SKILL.md +++ b/.github/skills/create-issue/SKILL.md @@ -13,7 +13,7 @@ If `gh` is not authenticated, stop and ask the user to authenticate before conti ## Looking up IDs -The hardcoded IDs below are correct for this repo as of 2026-04-28 13:47:49 UTC. If they ever change, or if you're working in a fork, re-run these queries to get fresh values: +The hardcoded IDs below are correct for this repo as of 2026-05-15 13:34:15 UTC. If they ever change, or if you're working in a fork, re-run these queries to get fresh values: ```bash # Repository node ID diff --git a/.github/skills/r-code/SKILL.md b/.github/skills/r-code/SKILL.md index 70350d8..707e335 100644 --- a/.github/skills/r-code/SKILL.md +++ b/.github/skills/r-code/SKILL.md @@ -6,7 +6,7 @@ description: Guide for writing R code. Use when writing new functions, designing # R code -This skill covers how to design and write R functions — including naming conventions, signatures, API conventions, input validation, error handling, and common pitfalls. For documenting functions, use the `document` skill. For tests, use the `tdd-workflow` skill. +This skill covers how to design and write R functions — including naming conventions, signatures, API conventions, input validation, condition handling, and common pitfalls. For documenting functions, use the `document` skill. For tests, use the `tdd-workflow` skill. ## Naming conventions @@ -184,9 +184,9 @@ Keep a function internal when: Internal helpers use a dot prefix (e.g. `.parse_response()`). -## Error handling +## Condition handling -Use `.pkg_abort()` (defined in `R/aaa-conditions.R`) rather than calling `cli::cli_abort()` directly. This wraps `stbl::pkg_abort()` and ensures consistent error class formatting: +Use `.pkg_abort()`, `.pkg_warn()`, and `.pkg_inform()` (defined in `R/aaa-conditions.R`) rather than calling `cli::cli_abort()`, `cli::cli_warn()`, or `cli::cli_inform()` directly. These wrap `stbl` condition helpers and ensure consistent class formatting: ```r .pkg_abort( diff --git a/.github/skills/tdd-workflow/SKILL.md b/.github/skills/tdd-workflow/SKILL.md index 826aa4c..d244189 100644 --- a/.github/skills/tdd-workflow/SKILL.md +++ b/.github/skills/tdd-workflow/SKILL.md @@ -133,8 +133,31 @@ test_that("process_data() errors on empty input (#42)", { }) ``` -Pass `transform = stbl::.transform_path(path)` to scrub volatile values (e.g. temp -paths) from the snapshot before comparison. +**Warnings thrown by this package** (via `.pkg_warn()`) should be tested with +`stbl::expect_pkg_warning_snapshot()`: + +```r +test_that("process_data() warns on dropped rows (#42)", { + stbl::expect_pkg_warning_snapshot( + process_data(data.frame(value = c(1, NA))), + "rapid", + "dropped_rows" + ) +}) +``` + +**Messages thrown by this package** (via `.pkg_inform()`) should be tested with +`stbl::expect_pkg_message_snapshot()`: + +```r +test_that("process_data() informs on defaults used (#42)", { + stbl::expect_pkg_message_snapshot( + process_data(data.frame(value = 1)), + "rapid", + "used_defaults" + ) +}) +``` **Errors thrown by `stbl`** (via `stbl::to_*()` / `stbl::stabilize_*()`) should be tested with `stbl::expect_pkg_error_classes()`. Since the message diff --git a/DESCRIPTION b/DESCRIPTION index 365d7b2..330149f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -24,7 +24,7 @@ Imports: rlang (>= 1.1.0), S7 (>= 0.2.0), snakecase, - stbl (>= 0.3.0), + stbl (>= 0.3.0.9000), tibble, tibblify (>= 0.4.0), xml2, @@ -33,8 +33,8 @@ Suggests: httr2, testthat (>= 3.0.0) Remotes: - stbl=wranglezone/stbl, - tibblify=wranglezone/tibblify + wranglezone/stbl, + wranglezone/tibblify Config/roxygen2/version: 8.0.0 Config/testthat/edition: 3 Config/testthat/parallel: true diff --git a/R/aaa-conditions.R b/R/aaa-conditions.R index 1def80a..9a3bbc1 100644 --- a/R/aaa-conditions.R +++ b/R/aaa-conditions.R @@ -1,4 +1,4 @@ -#' Raise a package-scoped error +#' Signal a package-scoped error #' #' @inheritParams .shared-params #' @inheritParams stbl::pkg_abort @@ -7,8 +7,9 @@ .pkg_abort <- function( message, subclass, - call = rlang::caller_env(), - message_env = rlang::caller_env(), + parent = NULL, + call = caller_env(), + message_env = caller_env(), ... ) { stbl::pkg_abort( @@ -17,6 +18,57 @@ subclass, call = call, message_env = message_env, + parent = parent, + ... + ) +} + +#' Signal a package-scoped warning +#' +#' @inheritParams .shared-params +#' @inheritParams stbl::pkg_warn +#' @returns `NULL`, invisibly (called for warning side effect). +#' @keywords internal +.pkg_warn <- function( + message, + subclass, + parent = NULL, + call = caller_env(), + message_env = caller_env(), + ... +) { + stbl::pkg_warn( + "rapid", + message, + subclass, + call = call, + message_env = message_env, + parent = parent, + ... + ) +} + +#' Signal a package-scoped message +#' +#' @inheritParams .shared-params +#' @inheritParams stbl::pkg_inform +#' @returns `NULL`, invisibly (called for warning side effect). +#' @keywords internal +.pkg_inform <- function( + message, + subclass, + parent = NULL, + call = caller_env(), + message_env = caller_env(), + ... +) { + stbl::pkg_inform( + "rapid", + message, + subclass, + call = call, + message_env = message_env, + parent = parent, ... ) } diff --git a/man/dot-pkg_abort.Rd b/man/dot-pkg_abort.Rd index a9b46ce..85a8870 100644 --- a/man/dot-pkg_abort.Rd +++ b/man/dot-pkg_abort.Rd @@ -2,13 +2,14 @@ % Please edit documentation in R/aaa-conditions.R \name{.pkg_abort} \alias{.pkg_abort} -\title{Raise a package-scoped error} +\title{Signal a package-scoped error} \usage{ .pkg_abort( message, subclass, - call = rlang::caller_env(), - message_env = rlang::caller_env(), + parent = NULL, + call = caller_env(), + message_env = caller_env(), ... ) } @@ -19,6 +20,9 @@ formatted with \code{\link[cli:cli_bullets]{cli::cli_bullets()}}.} \item{subclass}{(\code{character}) Class(es) to assign to the error. Will be prefixed by "\{package\}-error-".} +\item{parent}{A parent condition, as you might create during a +\code{\link[rlang:try_fetch]{rlang::try_fetch()}}. See \code{\link[rlang:abort]{rlang::abort()}} for additional information.} + \item{call}{(\code{environment}) The caller environment for error messages.} \item{message_env}{(\code{environment}) The execution environment to use to @@ -31,6 +35,6 @@ evaluate variables in error messages.} Does not return. } \description{ -Raise a package-scoped error +Signal a package-scoped error } \keyword{internal} diff --git a/man/dot-pkg_inform.Rd b/man/dot-pkg_inform.Rd new file mode 100644 index 0000000..a9c5464 --- /dev/null +++ b/man/dot-pkg_inform.Rd @@ -0,0 +1,40 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/aaa-conditions.R +\name{.pkg_inform} +\alias{.pkg_inform} +\title{Signal a package-scoped message} +\usage{ +.pkg_inform( + message, + subclass, + parent = NULL, + call = caller_env(), + message_env = caller_env(), + ... +) +} +\arguments{ +\item{message}{(\code{character}) The message for the new message condition. +Messages will be formatted with \code{\link[cli:cli_bullets]{cli::cli_bullets()}}.} + +\item{subclass}{(\code{character}) Class(es) to assign to the message. Will be +prefixed by "\{package\}-message-".} + +\item{parent}{A parent condition, as you might create during a +\code{\link[rlang:try_fetch]{rlang::try_fetch()}}. See \code{\link[rlang:abort]{rlang::abort()}} for additional information.} + +\item{call}{(\code{environment}) The caller environment for error messages.} + +\item{message_env}{(\code{environment}) The execution environment to use to +evaluate variables in error messages.} + +\item{...}{Additional parameters passed to \code{\link[cli:cli_abort]{cli::cli_inform()}} and on to +\code{\link[rlang:abort]{rlang::inform()}}.} +} +\value{ +\code{NULL}, invisibly (called for warning side effect). +} +\description{ +Signal a package-scoped message +} +\keyword{internal} diff --git a/man/dot-pkg_warn.Rd b/man/dot-pkg_warn.Rd new file mode 100644 index 0000000..b20532f --- /dev/null +++ b/man/dot-pkg_warn.Rd @@ -0,0 +1,40 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/aaa-conditions.R +\name{.pkg_warn} +\alias{.pkg_warn} +\title{Signal a package-scoped warning} +\usage{ +.pkg_warn( + message, + subclass, + parent = NULL, + call = caller_env(), + message_env = caller_env(), + ... +) +} +\arguments{ +\item{message}{(\code{character}) The message for the new warning. Messages will +be formatted with \code{\link[cli:cli_bullets]{cli::cli_bullets()}}.} + +\item{subclass}{(\code{character}) Class(es) to assign to the warning. Will be +prefixed by "\{package\}-warning-".} + +\item{parent}{A parent condition, as you might create during a +\code{\link[rlang:try_fetch]{rlang::try_fetch()}}. See \code{\link[rlang:abort]{rlang::abort()}} for additional information.} + +\item{call}{(\code{environment}) The caller environment for error messages.} + +\item{message_env}{(\code{environment}) The execution environment to use to +evaluate variables in error messages.} + +\item{...}{Additional parameters passed to \code{\link[cli:cli_abort]{cli::cli_warn()}} and on to +\code{\link[rlang:abort]{rlang::warn()}}.} +} +\value{ +\code{NULL}, invisibly (called for warning side effect). +} +\description{ +Signal a package-scoped warning +} +\keyword{internal}