确定所有包依赖项的最低 R 版本
Determine minimum R version for all package dependencies
我是一名包开发人员,想在 DESCRIPTION
文件中说明使用我的包所需的最低 R 版本。
available.packages
解析包的描述,但结果不是(容易)机器可读以查找递归依赖项,因为 Imports 和 Depends 字段是逗号分隔的文本,有时包含的包有版本要求。
解决方案描述于:
Listing R Package Dependencies Without Installing Packages 不是递归解。如果嵌套依赖项需要 R > 3.3,我想知道它。
至少,我希望看到 R 的最低版本以及导入、链接和依赖给定 CRAN 包的包。更好的办法是列出设置最低 R 或包版本的包。
通过消除具有更高版本要求的依赖项,我可以为更多使用他们无法修复的旧 R 版本的人提供服务:有些人仍在使用 R 2.x。
min_r_version <- function(package="ggplot2", exclude_main_pkg=TRUE) {
purrr::walk(c("tools", "purrr", "devtools", "stringi", "tidyr", "dplyr"),
require, character.only=TRUE)
deps <- package_dependencies(package, recursive=TRUE)
if (exclude_main_pkg) {
pkgs <- deps[[1]]
} else {
pkgs <- c(package, deps[[1]])
}
available.packages() %>%
as_data_frame() %>%
filter(Package %in% pkgs) %>%
select(Depends) %>%
unlist() -> pkg_list
# if main pkg only relied on core R packages (i.e. pkgs that aren't in CRAN) and we
# excluded the pkg itself from the min version calculation, this is an edge case we need
# to handle.
if (length(pkg_list) == 0) return("Unspecified")
stri_split_regex(pkg_list, "[,]") %>%
unlist() %>%
trimws() %>%
stri_match_all_regex(c("^R$|^R \(.*\)$")) %>%
unlist() %>%
discard(is.na(.)) %>%
unique() %>%
stri_replace_all_regex("[R >=\(\)]", "") %>%
data_frame(vs=.) %>%
separate(vs, c("a", "b", "c"), fill="right") %>%
mutate(c=ifelse(is.na(c), 0, c)) %>%
arrange(a, b, c) %>%
tail(1) %>%
unite(min, a:c, sep=".") -> vs
return(vs$min)
}
# did we handle the edge cases well enought?
base <- c("base", "compiler", "datasets", "grDevices", "graphics", "grid", "methods", "parallel", "profile", "splines", "stats", "stats4", "tcltk", "tools", "translations")
(base_reqs <- purrr::map_chr(base, min_r_version))
## [1] "Unspecified" "Unspecified" "Unspecified" "Unspecified" "Unspecified"
## [6] "Unspecified" "Unspecified" "Unspecified" "Unspecified" "Unspecified"
## [11] "Unspecified" "Unspecified" "Unspecified" "Unspecified" "Unspecified"
# a few of the "core" contributed pkgs rely on a pkg or two outside of base
# but many only rely on base packages, to this is another gd edge case to
# text for.
contrib <- c("KernSmooth", "MASS", "Matrix", "boot", "class", "cluster", "codetools", "foreign", "lattice", "mgcv", "nlme", "nnet", "rpart", "spatial", "survival")
contrib_reqs <- purrr::map_chr(contrib, min_r_version)
## [1] "Unspecified" "Unspecified" "3.0.0" "Unspecified" "3.1.0"
## [6] "Unspecified" "Unspecified" "Unspecified" "Unspecified" "3.0.2"
## [11] "3.0.0" "Unspecified" "Unspecified" "Unspecified" "3.0.1"
# See what the min version of R shld be for some of my pkgs
min_r_version("ggalt") # I claim R (>= 3.0.0) in DESCRIPTION
## [1] "3.1.2"
min_r_version("curlconverter") # I claim R (>= 3.0.0) in DESCRIPTION
## [1] "3.1.2"
min_r_version("iptools") # I claim R (>= 3.0.0) in DESCRIPTION
## [1] "3.0.0"
基于@hrbrmstr 的想法并使用基本函数编写,我现在使用以下函数:
min_r_version <- function(pkg, repo = "http://cloud.r-project.org") {
requireNamespace("tools")
requireNamespace("utils")
if (is.null(repo))
repo <- "https://cloud.r-project.org"
repo <- getOption("repos", default = repo)
avail <- utils::available.packages(utils::contrib.url(repos = repo))
deps <- tools::package_dependencies(pkg, db = avail, recursive = TRUE)
if (is.null(deps))
stop("package not found")
pkgs <- deps[[1]]
matches <- avail[ , "Package"] %in% pkgs
pkg_list <- avail[matches, "Depends"]
vers <- grep("^R$|^R \(.*\)$", pkg_list, value = TRUE)
vers <- gsub("[^0-9.]", "", vers)
if (length(vers) == 0)
return("Not specified")
max_ver = vers[1]
if (length(vers) == 1)
return(max_ver)
for (v in 2:length(vers))
if (utils::compareVersion(vers[v], max_ver) > 0)
max_ver <- vers[v]
max_ver
}
我是一名包开发人员,想在 DESCRIPTION
文件中说明使用我的包所需的最低 R 版本。
available.packages
解析包的描述,但结果不是(容易)机器可读以查找递归依赖项,因为 Imports 和 Depends 字段是逗号分隔的文本,有时包含的包有版本要求。
解决方案描述于: Listing R Package Dependencies Without Installing Packages 不是递归解。如果嵌套依赖项需要 R > 3.3,我想知道它。
至少,我希望看到 R 的最低版本以及导入、链接和依赖给定 CRAN 包的包。更好的办法是列出设置最低 R 或包版本的包。
通过消除具有更高版本要求的依赖项,我可以为更多使用他们无法修复的旧 R 版本的人提供服务:有些人仍在使用 R 2.x。
min_r_version <- function(package="ggplot2", exclude_main_pkg=TRUE) {
purrr::walk(c("tools", "purrr", "devtools", "stringi", "tidyr", "dplyr"),
require, character.only=TRUE)
deps <- package_dependencies(package, recursive=TRUE)
if (exclude_main_pkg) {
pkgs <- deps[[1]]
} else {
pkgs <- c(package, deps[[1]])
}
available.packages() %>%
as_data_frame() %>%
filter(Package %in% pkgs) %>%
select(Depends) %>%
unlist() -> pkg_list
# if main pkg only relied on core R packages (i.e. pkgs that aren't in CRAN) and we
# excluded the pkg itself from the min version calculation, this is an edge case we need
# to handle.
if (length(pkg_list) == 0) return("Unspecified")
stri_split_regex(pkg_list, "[,]") %>%
unlist() %>%
trimws() %>%
stri_match_all_regex(c("^R$|^R \(.*\)$")) %>%
unlist() %>%
discard(is.na(.)) %>%
unique() %>%
stri_replace_all_regex("[R >=\(\)]", "") %>%
data_frame(vs=.) %>%
separate(vs, c("a", "b", "c"), fill="right") %>%
mutate(c=ifelse(is.na(c), 0, c)) %>%
arrange(a, b, c) %>%
tail(1) %>%
unite(min, a:c, sep=".") -> vs
return(vs$min)
}
# did we handle the edge cases well enought?
base <- c("base", "compiler", "datasets", "grDevices", "graphics", "grid", "methods", "parallel", "profile", "splines", "stats", "stats4", "tcltk", "tools", "translations")
(base_reqs <- purrr::map_chr(base, min_r_version))
## [1] "Unspecified" "Unspecified" "Unspecified" "Unspecified" "Unspecified"
## [6] "Unspecified" "Unspecified" "Unspecified" "Unspecified" "Unspecified"
## [11] "Unspecified" "Unspecified" "Unspecified" "Unspecified" "Unspecified"
# a few of the "core" contributed pkgs rely on a pkg or two outside of base
# but many only rely on base packages, to this is another gd edge case to
# text for.
contrib <- c("KernSmooth", "MASS", "Matrix", "boot", "class", "cluster", "codetools", "foreign", "lattice", "mgcv", "nlme", "nnet", "rpart", "spatial", "survival")
contrib_reqs <- purrr::map_chr(contrib, min_r_version)
## [1] "Unspecified" "Unspecified" "3.0.0" "Unspecified" "3.1.0"
## [6] "Unspecified" "Unspecified" "Unspecified" "Unspecified" "3.0.2"
## [11] "3.0.0" "Unspecified" "Unspecified" "Unspecified" "3.0.1"
# See what the min version of R shld be for some of my pkgs
min_r_version("ggalt") # I claim R (>= 3.0.0) in DESCRIPTION
## [1] "3.1.2"
min_r_version("curlconverter") # I claim R (>= 3.0.0) in DESCRIPTION
## [1] "3.1.2"
min_r_version("iptools") # I claim R (>= 3.0.0) in DESCRIPTION
## [1] "3.0.0"
基于@hrbrmstr 的想法并使用基本函数编写,我现在使用以下函数:
min_r_version <- function(pkg, repo = "http://cloud.r-project.org") {
requireNamespace("tools")
requireNamespace("utils")
if (is.null(repo))
repo <- "https://cloud.r-project.org"
repo <- getOption("repos", default = repo)
avail <- utils::available.packages(utils::contrib.url(repos = repo))
deps <- tools::package_dependencies(pkg, db = avail, recursive = TRUE)
if (is.null(deps))
stop("package not found")
pkgs <- deps[[1]]
matches <- avail[ , "Package"] %in% pkgs
pkg_list <- avail[matches, "Depends"]
vers <- grep("^R$|^R \(.*\)$", pkg_list, value = TRUE)
vers <- gsub("[^0-9.]", "", vers)
if (length(vers) == 0)
return("Not specified")
max_ver = vers[1]
if (length(vers) == 1)
return(max_ver)
for (v in 2:length(vers))
if (utils::compareVersion(vers[v], max_ver) > 0)
max_ver <- vers[v]
max_ver
}