Skip to content

Commit

Permalink
add checks for namespace versions (#41)
Browse files Browse the repository at this point in the history
  • Loading branch information
jmbarbone committed Nov 27, 2023
1 parent d220292 commit fa4f722
Showing 1 changed file with 67 additions and 5 deletions.
72 changes: 67 additions & 5 deletions R/namespace.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,68 @@
#' @examples
#' isTRUE(require_namespace("base")) # returns invisibly
#' try(require_namespace("1package")) # (using a purposefully bad name)
#' require_namespace("base", "utils")
#' try(require_namespace("base>=3.5", "utils>4.0", "fuj==10.0"))
#' @export
require_namespace <- function(package, ...) {
pkgs <- c(package, ...)
for (pkg in pkgs) {
if (!isTRUE(try(requireNamespace(pkg, quietly = TRUE), silent = TRUE))) {
stop(cond_namespace(pkg))
}
package <- c(package, ...)
comparisons <- regmatches(package, regexec(">=?|<=?|==", package))
splits <- strsplit(package, comparisons, fixed = TRUE)

for (i in seq_along(package)) {
do_require_namespace(
package = splits[[i]][1],
version = splits[[i]][2],
operator = comparisons[[i]]
)
}

invisible(TRUE)
}

# helpers -----------------------------------------------------------------

do_require_namespace <- function(package, version, operator) {
tryCatch(
loadNamespace(package),
packageNotFoundError = function(e) {
stop(cond_namespace(package))
}
)

if (identical(operator, character())) {
return()
}

operator <- match.arg(trimws(operator), c(">", ">=", "==", "<=", "<"))
version <- as.package_version(version)

package_version <- function(package) {
# already loaded the namespace
if (package == "base") {
return(getRversion())
}

as.package_version(
get("spec", get(".__NAMESPACE__.", getNamespace(package)))[["version"]]
)
}

if (switch(
operator,
`>` = package_version(package) > version,
`>=` = package_version(package) >= version,
`==` = package_version(package) == version,
`<=` = package_version(package) <= version,
`<` = package_version(package) < version,
any = TRUE
)) {
stop(cond_namespace_version(package, version, operator))
}
}

# conditions --------------------------------------------------------------

cond_namespace <- function(package) {
new_condition(
msg = sprintf(
Expand All @@ -26,3 +76,15 @@ cond_namespace <- function(package) {
class = "namespace"
)
}

cond_namespace_version <- function(package, version, operator) {
new_condition(
msg = sprintf(
"Package '%s' not found with version %s%s",
package,
operator,
format(version)
),
class = "namespace_version"
)
}

0 comments on commit fa4f722

Please sign in to comment.