From 81006601f532a092a0d70aa8de07aa0dc463ff8e Mon Sep 17 00:00:00 2001 From: Matteo Delucchi Date: Thu, 14 Aug 2025 09:57:24 +0200 Subject: [PATCH 1/7] include a warning message about pak's detection limitations --- R/sysreqs.R | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/R/sysreqs.R b/R/sysreqs.R index 4e5b283f58..fad3f51fba 100644 --- a/R/sysreqs.R +++ b/R/sysreqs.R @@ -180,6 +180,17 @@ format.pak_sysreqs <- function(x, ...) { out } + # Add warning message about detection limitations + warning_msg <- c( + "", + cli$rule(left = "System package detection", col = "yellow"), + paste( + cli$col_yellow(cli$symbol$warning), + "System packages are detected via the system package manager only." + ), + "Software installed in non-standard locations may not be detected." + ) + c( cli$rule(left = "Install scripts", right = label), x$pre_install, @@ -195,7 +206,8 @@ format.pak_sysreqs <- function(x, ...) { " ", vcapply(pkgs, function(x) paste(cisort(x), collapse = ", ")) ) - } + }, + warning_msg ) } From ba5dce6fedb5187eb214020de7ce53bdb6770f75 Mon Sep 17 00:00:00 2001 From: Matteo Delucchi Date: Thu, 14 Aug 2025 10:11:36 +0200 Subject: [PATCH 2/7] handle disabled sysreqs appropriately --- R/sysreqs.R | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/R/sysreqs.R b/R/sysreqs.R index fad3f51fba..ac7bb44edc 100644 --- a/R/sysreqs.R +++ b/R/sysreqs.R @@ -42,13 +42,55 @@ sysreqs_db_list <- function(sysreqs_platform = NULL) { sysreqs_check_installed <- function(packages = NULL, library = .libPaths()[1]) { load_extra("pillar") - remote( + + # Check if sysreqs support is enabled in the config + sysreqs_enabled <- remote( + function() { + config <- pkgdepends::current_config() + config$get("sysreqs") + } + ) + + if (!sysreqs_enabled) { + cli::cli_alert_info( + "System requirements checking is disabled in the config." + ) + cli::cli_alert_info( + "Use {.code Sys.setenv('PKG_SYSREQS' = 'TRUE')} + or {.code options(pkg.sysreqs = TRUE)}." + ) + + # Return an empty data frame with the expected structure + result <- data.frame( + system_package = character(0), + installed = logical(0), + packages = I(list()), + pre_install = I(list()), + post_install = I(list()) + ) + class(result) <- c("pkg_sysreqs_check_result", class(result)) + return(invisible(pak_preformat(result))) + } + + result <- remote( function(...) { ret <- pkgdepends::sysreqs_check_installed(...) asNamespace("pak")$pak_preformat(ret) }, list(packages = packages, library = library) ) + + # Inform about detection method + if (nrow(result) > 0) { + cli::cli_alert_info( + "System packages checked via system package manager only." + ) + cli::cli_alert_info( + "Software in non-standard locations may not be detected." + ) + } + + result } sysreqs_fix_installed <- function(packages = NULL, library = .libPaths()[1]) { From 6aba81951ae86a23ed4b75fa78fa28ef34cba5ad Mon Sep 17 00:00:00 2001 From: Matteo Delucchi Date: Thu, 14 Aug 2025 10:19:19 +0200 Subject: [PATCH 3/7] include messaging in the main `pkg_sysreqs` function. Unsure if this is really needed... --- R/sysreqs.R | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/R/sysreqs.R b/R/sysreqs.R index ac7bb44edc..33e3847943 100644 --- a/R/sysreqs.R +++ b/R/sysreqs.R @@ -152,7 +152,15 @@ pkg_sysreqs <- function( sysreqs_platform = NULL ) { load_extra("pillar") - remote( + # Check if sysreqs support is enabled + sysreqs_enabled <- remote( + function() { + config <- pkgdepends::current_config() + config$get("sysreqs") + } + ) + + result <- remote( function(...) { get("pkg_sysreqs_internal", asNamespace("pak"))(...) }, @@ -163,6 +171,26 @@ pkg_sysreqs <- function( sysreqs_platform = sysreqs_platform ) ) + + # Add informational message if results are shown + if (sysreqs_enabled && length(result$install_scripts) > 0) { + cli::cli_alert_info( + "System packages detected via system package manager only." + ) + cli::cli_alert_info( + "Software in non-standard locations may require manual verification." + ) + } else if (!sysreqs_enabled) { + cli::cli_alert_info( + "System requirements lookup is disabled." + ) + cli::cli_alert_info( + "Enable with {.code Sys.setenv('PKG_SYSREQS' = 'TRUE')} + or {.code options(pkg.sysreqs = TRUE)}." + ) + } + + result } pkg_sysreqs_internal <- function( From e0e261e3af13e55302cc4e385aac6700e44f1dee Mon Sep 17 00:00:00 2001 From: Matteo Delucchi Date: Thu, 14 Aug 2025 10:21:37 +0200 Subject: [PATCH 4/7] updated the sysreq_fix_installed function to respect disabled sysreqs state. --- R/sysreqs.R | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/R/sysreqs.R b/R/sysreqs.R index 33e3847943..ac2097dc00 100644 --- a/R/sysreqs.R +++ b/R/sysreqs.R @@ -95,6 +95,36 @@ sysreqs_check_installed <- function(packages = NULL, library = .libPaths()[1]) { sysreqs_fix_installed <- function(packages = NULL, library = .libPaths()[1]) { load_extra("pillar") + + # Check if sysreqs support is enabled + sysreqs_enabled <- remote( + function() { + config <- pkgdepends::current_config() + config$get("sysreqs") + } + ) + + if (!sysreqs_enabled) { + cli::cli_alert_info( + "System requirements checking is disabled in the config." + ) + cli::cli_alert_info( + "Use {.code Sys.setenv('PKG_SYSREQS' = 'TRUE')} + or {.code options(pkg.sysreqs = TRUE)}." + ) + + # Return an empty data frame with the expected structure + result <- data.frame( + system_package = character(0), + installed = logical(0), + packages = I(list()), + pre_install = I(list()), + post_install = I(list()) + ) + class(result) <- c("pkg_sysreqs_check_result", class(result)) + return(invisible(pak_preformat(result))) + } + invisible(remote( function(...) { ret <- pkgdepends::sysreqs_fix_installed(...) From 8ff46a84a8bd63aebead0b4e8df8abc64aae4c06 Mon Sep 17 00:00:00 2001 From: Matteo Delucchi Date: Thu, 14 Aug 2025 10:28:11 +0200 Subject: [PATCH 5/7] show system requirements config status --- R/utils.R | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/R/utils.R b/R/utils.R index 8b13c3baf3..fcb6077405 100644 --- a/R/utils.R +++ b/R/utils.R @@ -359,3 +359,68 @@ rbind_expand <- function(..., .list = list()) { cisort <- function(x) { x[order(tolower(x))] } + +sysreqs_status <- function() { + config_info <- remote( + function() { + config <- pkgdepends::current_config() + list( + enabled = config$get("sysreqs"), + platform = config$get("sysreqs_platform"), + supported = pkgdepends::sysreqs_is_supported() + ) + } + ) + + # Check source of configuration + env_sysreqs <- Sys.getenv("PKG_SYSREQS", "") + opt_sysreqs <- getOption("pkg.sysreqs", NULL) + + config_source <- if (nzchar(env_sysreqs)) { + "environment variable PKG_SYSREQS" + } else if (!is.null(opt_sysreqs)) { + "option pkg.sysreqs" + } else { + "default" + } + + cli::cli_h2("System Requirements Configuration") + + if (config_info$enabled) { + cli::cli_alert_success( + "System requirements: {.strong enabled} (via {config_source})" + ) + + cli::cli_alert_info( + "Platform: {.val {config_info$platform}}" + ) + cli::cli_alert_info( + "Platform supported: {.val {config_info$supported}}" + ) + cli::cli_alert_warning( + "Detection method: {.strong system package manager only}" + ) + cli::cli_text("") + cli::cli_text( + " + Software in non-standard locations will {.strong not} be detected:" + ) + cli::cli_ul(c( + "Environment modules (lmod)", + "Custom compilation from source", + "Alternative package managers (conda, spack, nix)", + "User-space installations" + )) + } else { + cli::cli_alert_info( + "System requirements: {.strong disabled} (via {config_source})" + ) + cli::cli_text("") + cli::cli_text("To enable system requirements:") + cli::cli_code("Sys.setenv('PKG_SYSREQS' = 'TRUE')") + cli::cli_text("or") + cli::cli_code("options(pkg.sysreqs = TRUE)") + } + + invisible(config_info) +} From 7accadd0341c59c0d819ff02eee16e4bc4c7820f Mon Sep 17 00:00:00 2001 From: Matteo Delucchi Date: Thu, 14 Aug 2025 10:53:19 +0200 Subject: [PATCH 6/7] refactored into check_sysreqs_enabled --- R/sysreqs.R | 51 +++++++++++++++++++-------------------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/R/sysreqs.R b/R/sysreqs.R index ac2097dc00..ef16fad334 100644 --- a/R/sysreqs.R +++ b/R/sysreqs.R @@ -40,10 +40,7 @@ sysreqs_db_list <- function(sysreqs_platform = NULL) { ) } -sysreqs_check_installed <- function(packages = NULL, library = .libPaths()[1]) { - load_extra("pillar") - - # Check if sysreqs support is enabled in the config +check_sysreqs_enabled <- function() { sysreqs_enabled <- remote( function() { config <- pkgdepends::current_config() @@ -69,7 +66,19 @@ sysreqs_check_installed <- function(packages = NULL, library = .libPaths()[1]) { post_install = I(list()) ) class(result) <- c("pkg_sysreqs_check_result", class(result)) - return(invisible(pak_preformat(result))) + return(pak_preformat(result)) + } + + return(NULL) +} + +sysreqs_check_installed <- function(packages = NULL, library = .libPaths()[1]) { + load_extra("pillar") + + # Check if sysreqs is enabled, return early if disabled + disabled_result <- check_sysreqs_enabled() + if (!is.null(disabled_result)) { + return(invisible(disabled_result)) } result <- remote( @@ -96,33 +105,10 @@ sysreqs_check_installed <- function(packages = NULL, library = .libPaths()[1]) { sysreqs_fix_installed <- function(packages = NULL, library = .libPaths()[1]) { load_extra("pillar") - # Check if sysreqs support is enabled - sysreqs_enabled <- remote( - function() { - config <- pkgdepends::current_config() - config$get("sysreqs") - } - ) - - if (!sysreqs_enabled) { - cli::cli_alert_info( - "System requirements checking is disabled in the config." - ) - cli::cli_alert_info( - "Use {.code Sys.setenv('PKG_SYSREQS' = 'TRUE')} - or {.code options(pkg.sysreqs = TRUE)}." - ) - - # Return an empty data frame with the expected structure - result <- data.frame( - system_package = character(0), - installed = logical(0), - packages = I(list()), - pre_install = I(list()), - post_install = I(list()) - ) - class(result) <- c("pkg_sysreqs_check_result", class(result)) - return(invisible(pak_preformat(result))) + # Check if sysreqs is enabled, return early if disabled + disabled_result <- check_sysreqs_enabled() + if (!is.null(disabled_result)) { + return(invisible(disabled_result)) } invisible(remote( @@ -134,6 +120,7 @@ sysreqs_fix_installed <- function(packages = NULL, library = .libPaths()[1]) { )) } + #' Calculate system requirements of one of more packages #' #' @inheritParams pkg_install From 31c026fc63a5a0bfc66f2d943bfc78318782eadd Mon Sep 17 00:00:00 2001 From: Matteo Delucchi Date: Thu, 14 Aug 2025 10:53:38 +0200 Subject: [PATCH 7/7] improved documentation about detection limitations --- R/sysreqsdocs.R | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/R/sysreqsdocs.R b/R/sysreqsdocs.R index eb2585d2f6..f8ab5d1f37 100644 --- a/R/sysreqsdocs.R +++ b/R/sysreqsdocs.R @@ -205,3 +205,39 @@ sysreqs_fix_installed <- sysreqs_fix_installed #' sysreqs_list_system_packages()[1:10,] sysreqs_list_system_packages + +#' System requirements detection limitations +#' +#' @description +#' System requirements detection in pak only considers packages installed via the system package manager. +#' Supported package managers include: +#' * `apt` on Debian/Ubuntu systems +#' * `yum`/`dnf` on RedHat/CentOS/Fedora systems +#' * `zypper` on openSUSE/SUSE systems +#' * `apk` on Alpine systems +#' +#' pak does **not** detect software installed via: +#' * Environment modules (e.g., lmod, environment modules) +#' * Custom compilation from source +#' * Alternative package managers (e.g., conda, spack, nix, homebrew) +#' * User-space installations +#' * Software loaded via environment variables +#' +#' If your system has software installed in non-standard locations, you may need to: +#' * Install the required system packages via your system package manager +#' * Disable system requirements checking with `PKG_SYSREQS=FALSE` +#' * Use `options(pkg.sysreqs = FALSE)` to disable system requirements globally +#' +#' Use [sysreqs_status()] to check your current configuration. +#' +#' @name sysreqs_detection_limitations +#' @family system requirements functions +#' @keywords internal +#' @examplesIf Sys.getenv("IN_PKGDOWN") == "true" +#' # Check current system requirements status +#' sysreqs_status() +#' +#' # Disable system requirements globally +#' options(pkg.sysreqs = FALSE) + +check_sysreqs_enabled