From 9a857098f09e1ac47e72b918535c54712a560a11 Mon Sep 17 00:00:00 2001 From: Jon Harmon Date: Sun, 17 May 2026 09:22:14 -0500 Subject: [PATCH 1/2] Better read helpers Closes #99 --- DESCRIPTION | 1 + NAMESPACE | 3 + R/aaa-shared_params.R | 11 +-- R/generate_pkg.R | 20 ++-- R/read_config.R | 89 ++++++++++++++++-- R/use_beekeeper.R | 49 ++++++---- R/zzz.R | 3 +- inst/example_beekeeper_rapid.rds | Bin 0 -> 16332 bytes inst/example_config.yml | 5 + man/dot-generate_paths.Rd | 3 +- man/dot-shared-params.Rd | 11 +-- man/dot-write_config.Rd | 19 +++- man/dot-write_rapid.Rd | 9 +- man/generate_pkg.Rd | 13 +-- man/read_api_abbr.Rd | 36 +++++++ man/read_api_definition.Rd | 25 ++++- man/read_api_title.Rd | 36 +++++++ man/read_config.Rd | 18 +++- man/read_rapid_filename.Rd | 36 +++++++ man/use_beekeeper.Rd | 19 ++-- .../testthat/_fixtures/000-create_fixtures.R | 44 +++------ tests/testthat/_fixtures/fec/_beekeeper.yml | 2 +- .../_fixtures/fec/fec_subset_beekeeper.yml | 2 +- tests/testthat/_fixtures/guru/_beekeeper.yml | 2 +- .../testthat/_fixtures/trello/_beekeeper.yml | 2 +- tests/testthat/_snaps/read_config.md | 4 +- tests/testthat/helper.R | 13 ++- tests/testthat/test-read_config.R | 22 ++++- tests/testthat/test-use_beekeeper.R | 18 ++-- 29 files changed, 380 insertions(+), 135 deletions(-) create mode 100644 inst/example_beekeeper_rapid.rds create mode 100644 inst/example_config.yml create mode 100644 man/read_api_abbr.Rd create mode 100644 man/read_api_title.Rd create mode 100644 man/read_rapid_filename.Rd diff --git a/DESCRIPTION b/DESCRIPTION index baa3542..44108f6 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -21,6 +21,7 @@ Imports: fs, glue, httptest2, + memoise, nectar, purrr, rapid (>= 0.0.0.9003), diff --git a/NAMESPACE b/NAMESPACE index 9b0680f..1e0debf 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,8 +1,11 @@ # Generated by roxygen2: do not edit by hand export(generate_pkg) +export(read_api_abbr) export(read_api_definition) +export(read_api_title) export(read_config) +export(read_rapid_filename) export(use_beekeeper) if (getRversion() < "4.3.0") importFrom("S7", "@") importFrom(S7,class_any) diff --git a/R/aaa-shared_params.R b/R/aaa-shared_params.R index 7befacc..f4b5989 100644 --- a/R/aaa-shared_params.R +++ b/R/aaa-shared_params.R @@ -13,12 +13,11 @@ #' @param api_title (`character(1)`) The API title used in generated package #' files. #' @param base_path The root URL of the current project. -#' @param base_url (`character(1)`) The base URL used in generated test -#' helpers. +#' @param base_url (`character(1)`) The base URL used in generated test helpers. #' @param call (`environment`) The caller environment for error messages. #' @param config (`list`) Package-generation configuration data. -#' @param config_file (`character(1)` or `fs_path`) The path to a beekeeper yaml -#' config file. +#' @param config_filename (`character(1)` or `fs_path`) The path to a beekeeper +#' yaml config file (relative to the package root). #' @param data (`list`) Data passed to a template. #' @param dir (`character(1)`) The directory where a generated file should be #' written. @@ -51,8 +50,8 @@ #' operation identifier. #' @param pkg_dir (`character(1)` or `fs_path`) The directory containing package #' files. -#' @param rapid_file (`character(1)` or `fs_path`) The path to the R API -#' definition (rapid) file. +#' @param rapid_filename (`character(1)` or `fs_path`) The path to the R API +#' definition (rapid) file (relative to the package root). #' @param required (`logical`) Whether each parameter is required. #' @param security_arg_description (`character(1)`) The argument description. #' @param security_arg_name (`character(1)`) The argument name. diff --git a/R/generate_pkg.R b/R/generate_pkg.R index 3e50785..c95c37b 100644 --- a/R/generate_pkg.R +++ b/R/generate_pkg.R @@ -9,23 +9,21 @@ #' @returns (`character`, invisibly) Paths to files that were added or updated. #' @export generate_pkg <- function( - api_abbr = NULL, - api_definition = NULL, - api_title = NULL, - config_file = "_beekeeper.yml", + api_abbr = read_api_abbr(pkg_dir, config_filename), + api_definition = read_api_definition( + pkg_dir, + read_rapid_filename(pkg_dir, config_filename) + ), + api_title = read_api_title(pkg_dir, config_filename), + config_filename = "_beekeeper.yml", pkg_dir = "." ) { # TODO: Confirm that they use github & everything is committed. Error or warn # if not, letting them know that this can be destructive. Skip this check in # tests. .assert_is_pkg(pkg_dir) - if (purrr::some(list(api_abbr, api_definition, api_title), is.null)) { - config <- read_config(pkg_dir = pkg_dir, config_file = config_file) - } - api_abbr <- stbl::stabilize_character_scalar(api_abbr %||% config$api_abbr) - api_title <- stbl::stabilize_character_scalar(api_title %||% config$api_title) - api_definition <- api_definition %||% - read_api_definition(pkg_dir, config$rapid_file) + api_abbr <- stbl::stabilize_character_scalar(api_abbr) + api_title <- stbl::stabilize_character_scalar(api_title) config <- list(api_abbr = api_abbr, api_title = api_title) security_data <- .generate_security( api_abbr, diff --git a/R/read_config.R b/R/read_config.R index cd1874f..541d674 100644 --- a/R/read_config.R +++ b/R/read_config.R @@ -11,7 +11,7 @@ #' - `api_abbr` (`character(1)`): An abbreviation for the API, used in function #' names and other identifiers. #' - `api_version` (`character(1)`): The version of the API. -#' - `rapid_file` (`character(1)`): The name of the file (relative to the +#' - `rapid_filename` (`character(1)`): The name of the file (relative to the #' package root) where the API definition is stored as an RDS file. By default, #' this is `_beekeeper_rapid.rds`, and is generated by [use_beekeeper()] based #' on an OpenAPI definition file. @@ -20,10 +20,11 @@ #' #' @inheritParams .shared-params #' @returns (`list`) Configuration information, with elements `api_title`, -#' `api_abbr`, `api_version`, `rapid_file`, and `updated_on`. +#' `api_abbr`, `api_version`, `rapid_filename`, and `updated_on`. #' @export -read_config <- function(pkg_dir = ".", config_file = "_beekeeper.yml") { - config <- yaml::read_yaml(fs::path(pkg_dir, config_file)) +#' @family config readers +read_config <- function(pkg_dir = ".", config_filename = "_beekeeper.yml") { + config <- yaml::read_yaml(fs::path(pkg_dir, config_filename)) return(.stabilize_config(config)) } @@ -39,7 +40,9 @@ read_config <- function(pkg_dir = ".", config_file = "_beekeeper.yml") { config$api_version, allow_null = TRUE ) - config$rapid_file <- stbl::stabilize_character_scalar(config$rapid_file) + config$rapid_filename <- stbl::stabilize_character_scalar( + config$rapid_filename + ) config$updated_on <- config$updated_on %&&% strptime( config$updated_on, @@ -49,6 +52,70 @@ read_config <- function(pkg_dir = ".", config_file = "_beekeeper.yml") { return(config) } +.read_config_field <- function(field, pkg_dir, config_filename) { + read_config(pkg_dir, config_filename)[[field]] +} + +#' Read rapid_filename config field +#' +#' Read the `rapid_filename` field from a beekeeper config file. +#' +#' @inheritParams .shared-params +#' +#' @returns (`character(1)`) The `rapid_filename` field from the beekeeper +#' config file. +#' @export +#' @family config readers +#' @examples +#' read_rapid_filename( +#' pkg_dir = fs::path_package("beekeeper"), +#' config_filename = "example_config.yml" +#' ) +read_rapid_filename <- function( + pkg_dir = ".", + config_filename = "_beekeeper.yml" +) { + .read_config_field("rapid_filename", pkg_dir, config_filename) +} + +#' Read api_abbr config field +#' +#' Read the `api_abbr` field from a beekeeper config file. +#' +#' @inheritParams .shared-params +#' +#' @returns (`character(1)`) The `api_abbr` field from the beekeeper +#' config file. +#' @export +#' @family config readers +#' @examples +#' read_api_abbr( +#' pkg_dir = fs::path_package("beekeeper"), +#' config_filename = "example_config.yml" +#' ) +read_api_abbr <- function(pkg_dir = ".", config_filename = "_beekeeper.yml") { + .read_config_field("api_abbr", pkg_dir, config_filename) +} + +#' Read api_title config field +#' +#' Read the `api_title` field from a beekeeper config file. +#' +#' @inheritParams .shared-params +#' +#' @returns (`character(1)`) The `api_title` field from the beekeeper +#' config file. +#' @export +#' @family config readers +#' @examples +#' read_api_title( +#' pkg_dir = fs::path_package("beekeeper"), +#' config_filename = "example_config.yml" +#' ) +read_api_title <- function(pkg_dir = ".", config_filename = "_beekeeper.yml") { + .read_config_field("api_title", pkg_dir, config_filename) +} + #' Read an API definition file #' #' Reads an RDS file (default name `_beekeeper_rapid.rds`) with the API @@ -58,9 +125,17 @@ read_config <- function(pkg_dir = ".", config_file = "_beekeeper.yml") { #' @inheritParams .shared-params #' @returns (`rapid::class_rapid`) The definition of the API. #' @export +#' @family config readers +#' @examples +#' api_definition <- read_api_definition( +#' pkg_dir = fs::path_package("beekeeper"), +#' rapid_filename = "example_beekeeper_rapid.rds" +#' ) +#' class(api_definition) +#' api_definition@info@origin@url read_api_definition <- function( pkg_dir = ".", - rapid_file = "_beekeeper_rapid.rds" + rapid_filename = read_rapid_filename(pkg_dir) ) { - readRDS(fs::path(pkg_dir, rapid_file)) + readRDS(fs::path(pkg_dir, rapid_filename)) } diff --git a/R/use_beekeeper.R b/R/use_beekeeper.R index efecfe9..f9734d5 100644 --- a/R/use_beekeeper.R +++ b/R/use_beekeeper.R @@ -13,25 +13,29 @@ #' #' @returns (`character(1)`, invisibly) The path to the configuration file. The #' config file is written as a side effect of this function. The rapid object -#' is also written, and the path to that file is saved in the config file. +#' is also written, and the path to that file (relative to `pkg_dir`) is saved +#' in the config file. #' @export use_beekeeper <- function( x, api_abbr, ..., - config_file = "_beekeeper.yml", - rapid_file = "_beekeeper_rapid.rds" + pkg_dir = ".", + config_filename = "_beekeeper.yml", + rapid_filename = "_beekeeper_rapid.rds" ) { + .assert_is_pkg(pkg_dir) api_definition <- rapid::as_rapid(x) - rapid_file <- .write_rapid(api_definition, rapid_file) - config_file <- .write_config( + rapid_filename <- .write_rapid(api_definition, rapid_filename, pkg_dir) + config_filename <- .write_config( api_definition, api_abbr, - rapid_file, - config_file + rapid_filename, + config_filename, + pkg_dir ) - return(invisible(config_file)) + return(invisible(fs::path(pkg_dir, config_filename))) } #' Write the rapid definition file @@ -39,11 +43,11 @@ use_beekeeper <- function( #' @inheritParams .shared-params #' @returns (`character(1)`) The written file path. #' @keywords internal -.write_rapid <- function(api_definition, rapid_file) { - rapid_file <- stbl::stabilize_character_scalar(rapid_file) - saveRDS(api_definition, rapid_file) - usethis::use_build_ignore(rapid_file) - return(rapid_file) +.write_rapid <- function(api_definition, rapid_filename, pkg_dir) { + rapid_filename <- stbl::stabilize_character_scalar(rapid_filename) + saveRDS(api_definition, fs::path(pkg_dir, rapid_filename)) + usethis::use_build_ignore(rapid_filename) + return(rapid_filename) } #' Write the beekeeper config file @@ -51,19 +55,26 @@ use_beekeeper <- function( #' @inheritParams .shared-params #' @returns (`character(1)`) The written config file path. #' @keywords internal -.write_config <- function(api_definition, api_abbr, rapid_file, config_file) { - config_file <- stbl::stabilize_character_scalar(config_file) +.write_config <- function( + api_definition, + api_abbr, + rapid_filename, + config_filename, + pkg_dir +) { + config_filename <- stbl::stabilize_character_scalar(config_filename) update_time <- strptime(Sys.time(), format = "%Y-%m-%d %H:%M:%S", tz = "UTC") yaml::write_yaml( list( api_title = api_definition@info@title, api_abbr = stbl::stabilize_character_scalar(api_abbr), api_version = api_definition@info@version, - rapid_file = fs::path_rel(rapid_file, fs::path_dir(config_file)), + rapid_filename = rapid_filename, updated_on = as.character(update_time) ), - file = config_file + file = fs::path(pkg_dir, config_filename) ) - usethis::use_build_ignore(config_file) - return(config_file) + memoise::forget(read_config) + usethis::use_build_ignore(config_filename) + return(config_filename) } diff --git a/R/zzz.R b/R/zzz.R index 0b7eb0c..ecf8b07 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -1,5 +1,6 @@ -.onLoad <- function(...) { +.onLoad <- function(libname, pkgname) { S7::methods_register() # nocov + read_config <<- memoise::memoise(read_config) # nocov } # enable usage of @name in package code diff --git a/inst/example_beekeeper_rapid.rds b/inst/example_beekeeper_rapid.rds new file mode 100644 index 0000000000000000000000000000000000000000..aedfdf25d2ebc1a663ea6807464e67fc100b6ae6 GIT binary patch literal 16332 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 literal 0 HcmV?d00001 diff --git a/inst/example_config.yml b/inst/example_config.yml new file mode 100644 index 0000000..684c43b --- /dev/null +++ b/inst/example_config.yml @@ -0,0 +1,5 @@ +api_title: APIs.guru +api_abbr: guru +api_version: 2.2.0 +rapid_filename: example_beekeeper_rapid.rds +updated_on: 2026-05-12 07:57:02 diff --git a/man/dot-generate_paths.Rd b/man/dot-generate_paths.Rd index eb528a1..b434110 100644 --- a/man/dot-generate_paths.Rd +++ b/man/dot-generate_paths.Rd @@ -23,8 +23,7 @@ the API, for use in function names and environment variables.} \item{pagination_data}{(\code{list}) Pagination metadata used while generating path files.} -\item{base_url}{(\code{character(1)}) The base URL used in generated test -helpers.} +\item{base_url}{(\code{character(1)}) The base URL used in generated test helpers.} } \value{ (\code{character}) Generated file paths. diff --git a/man/dot-shared-params.Rd b/man/dot-shared-params.Rd index 7ff0906..19d92d9 100644 --- a/man/dot-shared-params.Rd +++ b/man/dot-shared-params.Rd @@ -20,15 +20,14 @@ files.} \item{base_path}{The root URL of the current project.} -\item{base_url}{(\code{character(1)}) The base URL used in generated test -helpers.} +\item{base_url}{(\code{character(1)}) The base URL used in generated test helpers.} \item{call}{(\code{environment}) The caller environment for error messages.} \item{config}{(\code{list}) Package-generation configuration data.} -\item{config_file}{(\code{character(1)} or \code{fs_path}) The path to a beekeeper yaml -config file.} +\item{config_filename}{(\code{character(1)} or \code{fs_path}) The path to a beekeeper +yaml config file (relative to the package root).} \item{data}{(\code{list}) Data passed to a template.} @@ -86,8 +85,8 @@ operation identifier.} \item{pkg_dir}{(\code{character(1)} or \code{fs_path}) The directory containing package files.} -\item{rapid_file}{(\code{character(1)} or \code{fs_path}) The path to the R API -definition (rapid) file.} +\item{rapid_filename}{(\code{character(1)} or \code{fs_path}) The path to the R API +definition (rapid) file (relative to the package root).} \item{required}{(\code{logical}) Whether each parameter is required.} diff --git a/man/dot-write_config.Rd b/man/dot-write_config.Rd index cd3ec2a..e72f958 100644 --- a/man/dot-write_config.Rd +++ b/man/dot-write_config.Rd @@ -4,7 +4,13 @@ \alias{.write_config} \title{Write the beekeeper config file} \usage{ -.write_config(api_definition, api_abbr, rapid_file, config_file) +.write_config( + api_definition, + api_abbr, + rapid_filename, + config_filename, + pkg_dir +) } \arguments{ \item{api_definition}{(\code{rapid::class_rapid}) The API definition to generate @@ -13,11 +19,14 @@ package code from.} \item{api_abbr}{(\code{character(1)}) A short (about 2-5 letter) abbreviation for the API, for use in function names and environment variables.} -\item{rapid_file}{(\code{character(1)} or \code{fs_path}) The path to the R API -definition (rapid) file.} +\item{rapid_filename}{(\code{character(1)} or \code{fs_path}) The path to the R API +definition (rapid) file (relative to the package root).} -\item{config_file}{(\code{character(1)} or \code{fs_path}) The path to a beekeeper yaml -config file.} +\item{config_filename}{(\code{character(1)} or \code{fs_path}) The path to a beekeeper +yaml config file (relative to the package root).} + +\item{pkg_dir}{(\code{character(1)} or \code{fs_path}) The directory containing package +files.} } \value{ (\code{character(1)}) The written config file path. diff --git a/man/dot-write_rapid.Rd b/man/dot-write_rapid.Rd index 45c7333..41bea7f 100644 --- a/man/dot-write_rapid.Rd +++ b/man/dot-write_rapid.Rd @@ -4,14 +4,17 @@ \alias{.write_rapid} \title{Write the rapid definition file} \usage{ -.write_rapid(api_definition, rapid_file) +.write_rapid(api_definition, rapid_filename, pkg_dir) } \arguments{ \item{api_definition}{(\code{rapid::class_rapid}) The API definition to generate package code from.} -\item{rapid_file}{(\code{character(1)} or \code{fs_path}) The path to the R API -definition (rapid) file.} +\item{rapid_filename}{(\code{character(1)} or \code{fs_path}) The path to the R API +definition (rapid) file (relative to the package root).} + +\item{pkg_dir}{(\code{character(1)} or \code{fs_path}) The directory containing package +files.} } \value{ (\code{character(1)}) The written file path. diff --git a/man/generate_pkg.Rd b/man/generate_pkg.Rd index 6e5607c..3aec639 100644 --- a/man/generate_pkg.Rd +++ b/man/generate_pkg.Rd @@ -5,10 +5,11 @@ \title{Use a beekeeper config file to generate code} \usage{ generate_pkg( - api_abbr = NULL, - api_definition = NULL, - api_title = NULL, - config_file = "_beekeeper.yml", + api_abbr = read_api_abbr(pkg_dir, config_filename), + api_definition = read_api_definition(pkg_dir, read_rapid_filename(pkg_dir, + config_filename)), + api_title = read_api_title(pkg_dir, config_filename), + config_filename = "_beekeeper.yml", pkg_dir = "." ) } @@ -22,8 +23,8 @@ package code from.} \item{api_title}{(\code{character(1)}) The API title used in generated package files.} -\item{config_file}{(\code{character(1)} or \code{fs_path}) The path to a beekeeper yaml -config file.} +\item{config_filename}{(\code{character(1)} or \code{fs_path}) The path to a beekeeper +yaml config file (relative to the package root).} \item{pkg_dir}{(\code{character(1)} or \code{fs_path}) The directory containing package files.} diff --git a/man/read_api_abbr.Rd b/man/read_api_abbr.Rd new file mode 100644 index 0000000..09774ca --- /dev/null +++ b/man/read_api_abbr.Rd @@ -0,0 +1,36 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/read_config.R +\name{read_api_abbr} +\alias{read_api_abbr} +\title{Read api_abbr config field} +\usage{ +read_api_abbr(pkg_dir = ".", config_filename = "_beekeeper.yml") +} +\arguments{ +\item{pkg_dir}{(\code{character(1)} or \code{fs_path}) The directory containing package +files.} + +\item{config_filename}{(\code{character(1)} or \code{fs_path}) The path to a beekeeper +yaml config file (relative to the package root).} +} +\value{ +(\code{character(1)}) The \code{api_abbr} field from the beekeeper +config file. +} +\description{ +Read the \code{api_abbr} field from a beekeeper config file. +} +\examples{ +read_api_abbr( + pkg_dir = fs::path_package("beekeeper"), + config_filename = "example_config.yml" +) +} +\seealso{ +Other config readers: +\code{\link[=read_api_definition]{read_api_definition()}}, +\code{\link[=read_api_title]{read_api_title()}}, +\code{\link[=read_config]{read_config()}}, +\code{\link[=read_rapid_filename]{read_rapid_filename()}} +} +\concept{config readers} diff --git a/man/read_api_definition.Rd b/man/read_api_definition.Rd index a043f2c..48dca93 100644 --- a/man/read_api_definition.Rd +++ b/man/read_api_definition.Rd @@ -4,14 +4,17 @@ \alias{read_api_definition} \title{Read an API definition file} \usage{ -read_api_definition(pkg_dir = ".", rapid_file = "_beekeeper_rapid.rds") +read_api_definition( + pkg_dir = ".", + rapid_filename = read_rapid_filename(pkg_dir) +) } \arguments{ \item{pkg_dir}{(\code{character(1)} or \code{fs_path}) The directory containing package files.} -\item{rapid_file}{(\code{character(1)} or \code{fs_path}) The path to the R API -definition (rapid) file.} +\item{rapid_filename}{(\code{character(1)} or \code{fs_path}) The path to the R API +definition (rapid) file (relative to the package root).} } \value{ (\code{rapid::class_rapid}) The definition of the API. @@ -21,3 +24,19 @@ Reads an RDS file (default name \verb{_beekeeper_rapid.rds}) with the API definition stored as a \code{\link[rapid:class_rapid]{rapid::class_rapid()}} object. This file is generated by \code{\link[=use_beekeeper]{use_beekeeper()}} based on an OpenAPI definition file. } +\examples{ +api_definition <- read_api_definition( + pkg_dir = fs::path_package("beekeeper"), + rapid_filename = "example_beekeeper_rapid.rds" +) +class(api_definition) +api_definition@info@origin@url +} +\seealso{ +Other config readers: +\code{\link[=read_api_abbr]{read_api_abbr()}}, +\code{\link[=read_api_title]{read_api_title()}}, +\code{\link[=read_config]{read_config()}}, +\code{\link[=read_rapid_filename]{read_rapid_filename()}} +} +\concept{config readers} diff --git a/man/read_api_title.Rd b/man/read_api_title.Rd new file mode 100644 index 0000000..9f1d6c2 --- /dev/null +++ b/man/read_api_title.Rd @@ -0,0 +1,36 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/read_config.R +\name{read_api_title} +\alias{read_api_title} +\title{Read api_title config field} +\usage{ +read_api_title(pkg_dir = ".", config_filename = "_beekeeper.yml") +} +\arguments{ +\item{pkg_dir}{(\code{character(1)} or \code{fs_path}) The directory containing package +files.} + +\item{config_filename}{(\code{character(1)} or \code{fs_path}) The path to a beekeeper +yaml config file (relative to the package root).} +} +\value{ +(\code{character(1)}) The \code{api_title} field from the beekeeper +config file. +} +\description{ +Read the \code{api_title} field from a beekeeper config file. +} +\examples{ +read_api_title( + pkg_dir = fs::path_package("beekeeper"), + config_filename = "example_config.yml" +) +} +\seealso{ +Other config readers: +\code{\link[=read_api_abbr]{read_api_abbr()}}, +\code{\link[=read_api_definition]{read_api_definition()}}, +\code{\link[=read_config]{read_config()}}, +\code{\link[=read_rapid_filename]{read_rapid_filename()}} +} +\concept{config readers} diff --git a/man/read_config.Rd b/man/read_config.Rd index 9dadade..664a7a9 100644 --- a/man/read_config.Rd +++ b/man/read_config.Rd @@ -4,18 +4,18 @@ \alias{read_config} \title{Read a beekeeper config file} \usage{ -read_config(pkg_dir = ".", config_file = "_beekeeper.yml") +read_config(pkg_dir = ".", config_filename = "_beekeeper.yml") } \arguments{ \item{pkg_dir}{(\code{character(1)} or \code{fs_path}) The directory containing package files.} -\item{config_file}{(\code{character(1)} or \code{fs_path}) The path to a beekeeper yaml -config file.} +\item{config_filename}{(\code{character(1)} or \code{fs_path}) The path to a beekeeper +yaml config file (relative to the package root).} } \value{ (\code{list}) Configuration information, with elements \code{api_title}, -\code{api_abbr}, \code{api_version}, \code{rapid_file}, and \code{updated_on}. +\code{api_abbr}, \code{api_version}, \code{rapid_filename}, and \code{updated_on}. } \description{ Reads a YAML file (default name \verb{_beekeeper.yml}) with configuration @@ -30,7 +30,7 @@ and messages. \item \code{api_abbr} (\code{character(1)}): An abbreviation for the API, used in function names and other identifiers. \item \code{api_version} (\code{character(1)}): The version of the API. -\item \code{rapid_file} (\code{character(1)}): The name of the file (relative to the +\item \code{rapid_filename} (\code{character(1)}): The name of the file (relative to the package root) where the API definition is stored as an RDS file. By default, this is \verb{_beekeeper_rapid.rds}, and is generated by \code{\link[=use_beekeeper]{use_beekeeper()}} based on an OpenAPI definition file. @@ -38,3 +38,11 @@ on an OpenAPI definition file. last updated, in the format "YYYY-MM-DD HH:MM:SS" (UTC). } } +\seealso{ +Other config readers: +\code{\link[=read_api_abbr]{read_api_abbr()}}, +\code{\link[=read_api_definition]{read_api_definition()}}, +\code{\link[=read_api_title]{read_api_title()}}, +\code{\link[=read_rapid_filename]{read_rapid_filename()}} +} +\concept{config readers} diff --git a/man/read_rapid_filename.Rd b/man/read_rapid_filename.Rd new file mode 100644 index 0000000..94690ed --- /dev/null +++ b/man/read_rapid_filename.Rd @@ -0,0 +1,36 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/read_config.R +\name{read_rapid_filename} +\alias{read_rapid_filename} +\title{Read rapid_filename config field} +\usage{ +read_rapid_filename(pkg_dir = ".", config_filename = "_beekeeper.yml") +} +\arguments{ +\item{pkg_dir}{(\code{character(1)} or \code{fs_path}) The directory containing package +files.} + +\item{config_filename}{(\code{character(1)} or \code{fs_path}) The path to a beekeeper +yaml config file (relative to the package root).} +} +\value{ +(\code{character(1)}) The \code{rapid_filename} field from the beekeeper +config file. +} +\description{ +Read the \code{rapid_filename} field from a beekeeper config file. +} +\examples{ +read_rapid_filename( + pkg_dir = fs::path_package("beekeeper"), + config_filename = "example_config.yml" +) +} +\seealso{ +Other config readers: +\code{\link[=read_api_abbr]{read_api_abbr()}}, +\code{\link[=read_api_definition]{read_api_definition()}}, +\code{\link[=read_api_title]{read_api_title()}}, +\code{\link[=read_config]{read_config()}} +} +\concept{config readers} diff --git a/man/use_beekeeper.Rd b/man/use_beekeeper.Rd index 2a6b33c..75fd578 100644 --- a/man/use_beekeeper.Rd +++ b/man/use_beekeeper.Rd @@ -8,8 +8,9 @@ use_beekeeper( x, api_abbr, ..., - config_file = "_beekeeper.yml", - rapid_file = "_beekeeper_rapid.rds" + pkg_dir = ".", + config_filename = "_beekeeper.yml", + rapid_filename = "_beekeeper_rapid.rds" ) } \arguments{ @@ -23,16 +24,20 @@ the API, for use in function names and environment variables.} \item{...}{These dots are for future extensions and must be empty.} -\item{config_file}{(\code{character(1)} or \code{fs_path}) The path to a beekeeper yaml -config file.} +\item{pkg_dir}{(\code{character(1)} or \code{fs_path}) The directory containing package +files.} -\item{rapid_file}{(\code{character(1)} or \code{fs_path}) The path to the R API -definition (rapid) file.} +\item{config_filename}{(\code{character(1)} or \code{fs_path}) The path to a beekeeper +yaml config file (relative to the package root).} + +\item{rapid_filename}{(\code{character(1)} or \code{fs_path}) The path to the R API +definition (rapid) file (relative to the package root).} } \value{ (\code{character(1)}, invisibly) The path to the configuration file. The config file is written as a side effect of this function. The rapid object -is also written, and the path to that file is saved in the config file. +is also written, and the path to that file (relative to \code{pkg_dir}) is saved +in the config file. } \description{ Create a configuration file for a package to use beekeeper. The configuration diff --git a/tests/testthat/_fixtures/000-create_fixtures.R b/tests/testthat/_fixtures/000-create_fixtures.R index 68475c9..e5d82c5 100644 --- a/tests/testthat/_fixtures/000-create_fixtures.R +++ b/tests/testthat/_fixtures/000-create_fixtures.R @@ -1,27 +1,16 @@ apid_url <- "https://api.apis.guru/v2/specs/apis.guru/2.2.0/openapi.yaml" api_abbr <- "guru" -rapid_write_path <- test_path(glue::glue( - "_fixtures/{api_abbr}/_beekeeper_rapid.rds" -)) -config_path <- test_path(glue::glue( - "_fixtures/{api_abbr}/_beekeeper.yml" -)) apid_url |> url() |> use_beekeeper( api_abbr = api_abbr, - config_file = config_path, - rapid_file = rapid_write_path + pkg_path = test_path("_fixtures", api_abbr), + config_filename = "_beekeeper.yml", + rapid_filename = "_beekeeper_rapid.rds" ) apid_url <- "https://api.apis.guru/v2/specs/fec.gov/1.0/openapi.yaml" api_abbr <- "fec" -rapid_write_path <- test_path(glue::glue( - "_fixtures/{api_abbr}/_beekeeper_rapid.rds" -)) -config_path <- test_path(glue::glue( - "_fixtures/{api_abbr}/_beekeeper.yml" -)) fec_apid <- apid_url |> url() |> yaml::read_yaml() @@ -37,8 +26,9 @@ fec_rapid <- rapid::as_rapid(fec_apid) fec_rapid |> use_beekeeper( api_abbr = api_abbr, - config_file = config_path, - rapid_file = rapid_write_path + pkg_path = test_path("_fixtures", api_abbr), + config_filename = "_beekeeper.yml", + rapid_filename = "_beekeeper_rapid.rds" ) fec_rapid@paths <- rapid::as_paths({ x <- fec_rapid@paths |> @@ -48,27 +38,16 @@ fec_rapid@paths <- rapid::as_paths({ x$tags <- NULL x }) -rapid_write_path <- test_path(glue::glue( - "_fixtures/{api_abbr}/{api_abbr}_subset_rapid.rds" -)) -config_path <- test_path(glue::glue( - "_fixtures/{api_abbr}/{api_abbr}_subset_beekeeper.yml" -)) fec_rapid |> use_beekeeper( api_abbr = api_abbr, - config_file = config_path, - rapid_file = rapid_write_path + pkg_path = test_path("_fixtures", api_abbr), + config_filename = "fec_subset_beekeeper.yml", + rapid_filename = "fec_subset_rapid.rds" ) apid_url <- "https://api.apis.guru/v2/specs/trello.com/1.0/openapi.yaml" api_abbr <- "trello" -rapid_write_path <- test_path(glue::glue( - "_fixtures/{api_abbr}/_beekeeper_rapid.rds" -)) -config_path <- test_path(glue::glue( - "_fixtures/{api_abbr}/_beekeeper.yml" -)) trello_rapid <- apid_url |> url() |> rapid::as_rapid() @@ -83,8 +62,9 @@ trello_rapid@paths <- rapid::as_paths({ trello_rapid |> use_beekeeper( api_abbr = api_abbr, - config_file = config_path, - rapid_file = rapid_write_path + pkg_path = test_path("_fixtures", api_abbr), + config_filename = "_beekeeper.yml", + rapid_filename = "_beekeeper_rapid.rds" ) cli::cli_warn("Revert .Rbuildignore") diff --git a/tests/testthat/_fixtures/fec/_beekeeper.yml b/tests/testthat/_fixtures/fec/_beekeeper.yml index cbd7a2a..d90267f 100644 --- a/tests/testthat/_fixtures/fec/_beekeeper.yml +++ b/tests/testthat/_fixtures/fec/_beekeeper.yml @@ -1,5 +1,5 @@ api_title: OpenFEC api_abbr: fec api_version: '1.0' -rapid_file: _beekeeper_rapid.rds +rapid_filename: _beekeeper_rapid.rds updated_on: 2026-05-12 07:57:21 diff --git a/tests/testthat/_fixtures/fec/fec_subset_beekeeper.yml b/tests/testthat/_fixtures/fec/fec_subset_beekeeper.yml index 1f25328..448746c 100644 --- a/tests/testthat/_fixtures/fec/fec_subset_beekeeper.yml +++ b/tests/testthat/_fixtures/fec/fec_subset_beekeeper.yml @@ -1,5 +1,5 @@ api_title: OpenFEC api_abbr: fec api_version: '1.0' -rapid_file: fec_subset_rapid.rds +rapid_filename: fec_subset_rapid.rds updated_on: 2026-05-12 07:57:29 diff --git a/tests/testthat/_fixtures/guru/_beekeeper.yml b/tests/testthat/_fixtures/guru/_beekeeper.yml index 3c59cd4..35a1cf4 100644 --- a/tests/testthat/_fixtures/guru/_beekeeper.yml +++ b/tests/testthat/_fixtures/guru/_beekeeper.yml @@ -1,5 +1,5 @@ api_title: APIs.guru api_abbr: guru api_version: 2.2.0 -rapid_file: _beekeeper_rapid.rds +rapid_filename: _beekeeper_rapid.rds updated_on: 2026-05-12 07:57:02 diff --git a/tests/testthat/_fixtures/trello/_beekeeper.yml b/tests/testthat/_fixtures/trello/_beekeeper.yml index e7113dc..8441ca9 100644 --- a/tests/testthat/_fixtures/trello/_beekeeper.yml +++ b/tests/testthat/_fixtures/trello/_beekeeper.yml @@ -1,5 +1,5 @@ api_title: Trello api_abbr: trello api_version: '1.0' -rapid_file: _beekeeper_rapid.rds +rapid_filename: _beekeeper_rapid.rds updated_on: 2026-05-12 07:57:43 diff --git a/tests/testthat/_snaps/read_config.md b/tests/testthat/_snaps/read_config.md index 0a9e06d..be541e9 100644 --- a/tests/testthat/_snaps/read_config.md +++ b/tests/testthat/_snaps/read_config.md @@ -1,4 +1,4 @@ -# read_config() reads configs +# read_config() reads configs (#82) Code config @@ -12,7 +12,7 @@ $api_version [1] "2.2.0" - $rapid_file + $rapid_filename [1] "_beekeeper_rapid.rds" $updated_on diff --git a/tests/testthat/helper.R b/tests/testthat/helper.R index 60bc6d2..5308453 100644 --- a/tests/testthat/helper.R +++ b/tests/testthat/helper.R @@ -35,8 +35,8 @@ scrub_updated <- function(input) { scrub_rapid_file_location <- function(input) { sub( - "rapid_file: .*$", - "rapid_file: RAPID_FILE_PATH", + "rapid_filename: .*$", + "rapid_filename: RAPID_FILE_PATH", input ) } @@ -104,15 +104,20 @@ guru_config <- read_config(pkg_dir = test_path("_fixtures", "guru")) guru_api_definition <- read_api_definition( pkg_dir = test_path("_fixtures", "guru") ) +memoise::forget(read_config) + trello_config <- read_config(pkg_dir = test_path("_fixtures", "trello")) trello_api_definition <- read_api_definition( pkg_dir = test_path("_fixtures", "trello") ) +memoise::forget(read_config) + fec_config <- read_config( pkg_dir = test_path("_fixtures", "fec"), - config_file = "fec_subset_beekeeper.yml" + config_filename = "fec_subset_beekeeper.yml" ) fec_api_definition <- read_api_definition( pkg_dir = test_path("_fixtures", "fec"), - rapid_file = "fec_subset_rapid.rds" + rapid_filename = "fec_subset_rapid.rds" ) +memoise::forget(read_config) diff --git a/tests/testthat/test-read_config.R b/tests/testthat/test-read_config.R index 7a5a738..84b890b 100644 --- a/tests/testthat/test-read_config.R +++ b/tests/testthat/test-read_config.R @@ -1,4 +1,5 @@ -test_that("read_config() reads configs", { +test_that("read_config() reads configs (#82)", { + withr::defer(memoise::forget(read_config)) config <- read_config(pkg_dir = test_path("_fixtures", "guru")) expect_s3_class(config$updated_on, c("POSIXlt", "POSIXt")) expect_snapshot({ @@ -6,9 +7,20 @@ test_that("read_config() reads configs", { }) }) -test_that("read_api_definition() reads api_definitions", { - api_definition <- read_api_definition( - pkg_dir = test_path("_fixtures", "guru") +test_that("read_api_definition() reads api definitions (#82)", { + withr::defer(memoise::forget(read_config)) + expect_s7_class( + read_api_definition(test_path("_fixtures", "guru")), + rapid::class_rapid ) - expect_s7_class(api_definition, rapid::class_rapid) +}) + +test_that("read_api_abbr() reads api abbrs (#99)", { + withr::defer(memoise::forget(read_config)) + expect_equal(read_api_abbr(test_path("_fixtures", "guru")), "guru") +}) + +test_that("read_api_title() reads api titles (#99)", { + withr::defer(memoise::forget(read_config)) + expect_equal(read_api_title(test_path("_fixtures", "guru")), "APIs.guru") }) diff --git a/tests/testthat/test-use_beekeeper.R b/tests/testthat/test-use_beekeeper.R index 0550003..5b868f7 100644 --- a/tests/testthat/test-use_beekeeper.R +++ b/tests/testthat/test-use_beekeeper.R @@ -1,22 +1,26 @@ test_that("use_beekeeper writes a yml config (#10)", { + pkg_tempdir <- withr::local_tempdir() local_mocked_bindings( use_build_ignore = function(...) { invisible(TRUE) }, .package = "usethis" ) - config_path <- withr::local_tempfile(fileext = ".yml") - rapid_write_path <- withr::local_tempfile(fileext = ".rds") + local_mocked_bindings( + .assert_is_pkg = function(pkg_dir) { + expect_identical(pkg_dir, pkg_tempdir) + invisible(NULL) + } + ) test_result <- use_beekeeper( guru_api_definition, api_abbr = "guru", - config_file = config_path, - rapid_file = rapid_write_path + pkg_dir = pkg_tempdir ) - expect_identical(test_result, config_path) - reread_rapid <- readRDS(rapid_write_path) + expect_identical(test_result, fs::path(pkg_tempdir, "_beekeeper.yml")) + reread_rapid <- readRDS(fs::path(pkg_tempdir, "_beekeeper_rapid.rds")) expect_identical(guru_api_definition, reread_rapid) - test_result_file <- scrub_config(readLines(config_path)) + test_result_file <- scrub_config(readLines(test_result)) expected_result_file <- scrub_config( readLines(test_path("_fixtures", "guru", "_beekeeper.yml")) ) From ab254248065b4d0b89e5fd61a4a212a236f68b81 Mon Sep 17 00:00:00 2001 From: Jon Harmon Date: Sun, 17 May 2026 11:44:49 -0500 Subject: [PATCH 2/2] Apply changes from copilot code review --- R/read_config.R | 2 ++ R/use_beekeeper.R | 5 +++-- tests/testthat/_fixtures/000-create_fixtures.R | 8 ++++---- tests/testthat/test-use_beekeeper.R | 3 +++ 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/R/read_config.R b/R/read_config.R index 541d674..c63e895 100644 --- a/R/read_config.R +++ b/R/read_config.R @@ -24,6 +24,7 @@ #' @export #' @family config readers read_config <- function(pkg_dir = ".", config_filename = "_beekeeper.yml") { + .assert_is_pkg(pkg_dir) config <- yaml::read_yaml(fs::path(pkg_dir, config_filename)) return(.stabilize_config(config)) } @@ -137,5 +138,6 @@ read_api_definition <- function( pkg_dir = ".", rapid_filename = read_rapid_filename(pkg_dir) ) { + .assert_is_pkg(pkg_dir) readRDS(fs::path(pkg_dir, rapid_filename)) } diff --git a/R/use_beekeeper.R b/R/use_beekeeper.R index f9734d5..04be554 100644 --- a/R/use_beekeeper.R +++ b/R/use_beekeeper.R @@ -24,6 +24,7 @@ use_beekeeper <- function( config_filename = "_beekeeper.yml", rapid_filename = "_beekeeper_rapid.rds" ) { + rlang::check_dots_empty() .assert_is_pkg(pkg_dir) api_definition <- rapid::as_rapid(x) rapid_filename <- .write_rapid(api_definition, rapid_filename, pkg_dir) @@ -46,7 +47,7 @@ use_beekeeper <- function( .write_rapid <- function(api_definition, rapid_filename, pkg_dir) { rapid_filename <- stbl::stabilize_character_scalar(rapid_filename) saveRDS(api_definition, fs::path(pkg_dir, rapid_filename)) - usethis::use_build_ignore(rapid_filename) + usethis::with_project(pkg_dir, usethis::use_build_ignore(rapid_filename)) return(rapid_filename) } @@ -75,6 +76,6 @@ use_beekeeper <- function( file = fs::path(pkg_dir, config_filename) ) memoise::forget(read_config) - usethis::use_build_ignore(config_filename) + usethis::with_project(pkg_dir, usethis::use_build_ignore(config_filename)) return(config_filename) } diff --git a/tests/testthat/_fixtures/000-create_fixtures.R b/tests/testthat/_fixtures/000-create_fixtures.R index e5d82c5..7561dce 100644 --- a/tests/testthat/_fixtures/000-create_fixtures.R +++ b/tests/testthat/_fixtures/000-create_fixtures.R @@ -4,7 +4,7 @@ apid_url |> url() |> use_beekeeper( api_abbr = api_abbr, - pkg_path = test_path("_fixtures", api_abbr), + pkg_dir = test_path("_fixtures", api_abbr), config_filename = "_beekeeper.yml", rapid_filename = "_beekeeper_rapid.rds" ) @@ -26,7 +26,7 @@ fec_rapid <- rapid::as_rapid(fec_apid) fec_rapid |> use_beekeeper( api_abbr = api_abbr, - pkg_path = test_path("_fixtures", api_abbr), + pkg_dir = test_path("_fixtures", api_abbr), config_filename = "_beekeeper.yml", rapid_filename = "_beekeeper_rapid.rds" ) @@ -41,7 +41,7 @@ fec_rapid@paths <- rapid::as_paths({ fec_rapid |> use_beekeeper( api_abbr = api_abbr, - pkg_path = test_path("_fixtures", api_abbr), + pkg_dir = test_path("_fixtures", api_abbr), config_filename = "fec_subset_beekeeper.yml", rapid_filename = "fec_subset_rapid.rds" ) @@ -62,7 +62,7 @@ trello_rapid@paths <- rapid::as_paths({ trello_rapid |> use_beekeeper( api_abbr = api_abbr, - pkg_path = test_path("_fixtures", api_abbr), + pkg_dir = test_path("_fixtures", api_abbr), config_filename = "_beekeeper.yml", rapid_filename = "_beekeeper_rapid.rds" ) diff --git a/tests/testthat/test-use_beekeeper.R b/tests/testthat/test-use_beekeeper.R index 5b868f7..cc77f6d 100644 --- a/tests/testthat/test-use_beekeeper.R +++ b/tests/testthat/test-use_beekeeper.R @@ -4,6 +4,9 @@ test_that("use_beekeeper writes a yml config (#10)", { use_build_ignore = function(...) { invisible(TRUE) }, + with_project = function(...) { + invisible(NULL) + }, .package = "usethis" ) local_mocked_bindings(