-
Notifications
You must be signed in to change notification settings - Fork 0
/
dependencies.R
111 lines (95 loc) · 2.83 KB
/
dependencies.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# TODO replace this with upstream https://github.com/dataheld/elf/issues/1
#' Checks if a package is installed and *informs* the user if not
#'
#' This is wrapper around [rlang::check_installed];
#' instead of erroring out if the check fails it returns `FALSE`.
#' However, unlike [rlang::is_installed], it emits a message to the user.
#'
#' @inheritParams rlang::check_installed
#' @inheritDotParams rlang::check_installed
#' @example inst/examples/dependencies/is_installed2/missing.R
#' @example inst/examples/dependencies/is_installed2/present.R
#' @family dependencies helper
#' @export
is_installed2 <- function(...) {
if (rlang::is_installed(...)) {
return(TRUE)
}
rlang::try_fetch(
# TODO this should only interact with the user as per .frequency
# might get annoying otherwise
# but that is blocked by deep integration in rlang
rlang::check_installed(...),
error = function(cnd) {
inform_missing_pkgs(...)
}
)
rlang::is_installed(...)
}
inform_missing_pkgs <- function(pkg, ...) {
rlang::inform(
message = cnd_header.elf_message_package_not_found(
cnd = new_message_package_not_found(pkg = pkg, ...)
),
.frequency = "once",
.frequency_id = paste0("elf_message_package_not_found", pkg, collapse = "_")
)
}
# copied, slightly adapted from rlang
# nolint start
new_message_package_not_found <- function(pkg,
version = NULL,
compare = NULL,
reason = NULL) {
rlang::message_cnd(
class = "elf_message_package_not_found",
pkg = pkg,
version = version,
compare = compare,
reason = reason
)
}
cnd_header.elf_message_package_not_found <- function(cnd) {
pkg <- cnd$pkg
version <- cnd$version
compare <- cnd$compare
reason <- cnd$reason
n <- length(pkg)
# Quote with `"` to make it easier to copy/paste (#1447)
pkg_enum <- chr_quoted(cnd$pkg, type = "\"")
if (!rlang::is_null(version)) {
pkg_enum <- purrr::list_c(purrr::pmap(list(pkg_enum, compare, version), function(p, o, v) {
if (rlang::is_na(v)) {
p
} else {
sprintf("%s (%s %s)", p, o, v)
}
}))
}
pkg_enum <- oxford_comma(pkg_enum, final = "and")
info <- cli::pluralize("The optional package{?s} {pkg_enum} {?is/are} missing.")
if (rlang::is_null(reason)) {
paste0(info, ".")
} else {
paste(info, reason)
}
}
chr_quoted <- function(chr, type = "`") {
paste0(type, chr, type)
}
oxford_comma <- function(chr, sep = ", ", final = "or") {
n <- length(chr)
if (n < 2) {
return(chr)
}
head <- chr[seq_len(n - 1)]
last <- chr[n]
head <- paste(head, collapse = sep)
# Write a or b. But a, b, or c.
if (n > 2) {
paste0(head, sep, final, " ", last)
} else {
paste0(head, " ", final, " ", last)
}
}
# nolint end