Skip to content

Commit aeb17f7

Browse files
committed
Return description and author for installed packages
Extend .ps.rpc.pkg_list to return `description` and `author` alongside the existing fields so Positron's Packages pane card view can render them. Both are normalized for display: descriptions collapse whitespace so multi-line text fits on one line, and author strips trailing `<email>` markers from Maintainer values. All three methods (pak / base / renv) populate the new fields. base and renv share a helper that wraps utils::installed.packages() so the lib lookup only differs by `lib.loc`. See posit-dev/positron#12925
1 parent f9e0c78 commit aeb17f7

1 file changed

Lines changed: 48 additions & 23 deletions

File tree

crates/ark/src/modules/positron/packages_pane.R

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,49 @@
88
# This file contains RPC functions for the packages pane.
99
# These functions are called via callMethod from the Positron R extension.
1010

11+
# Normalize a DESCRIPTION field value for display: collapse whitespace/newlines
12+
# into single spaces so a multi-line Description fits on one line in the UI.
13+
.ps.pkg_description_text <- function(value) {
14+
if (is.null(value) || is.na(value)) {
15+
return("")
16+
}
17+
value <- as.character(value)
18+
value <- gsub("\\s+", " ", value, perl = TRUE)
19+
trimws(value)
20+
}
21+
22+
# Normalize a Maintainer/Author value for display: collapse whitespace and strip
23+
# trailing email addresses in angle brackets (e.g., "Hadley Wickham <h@posit.co>"
24+
# becomes "Hadley Wickham").
25+
.ps.pkg_author_text <- function(value) {
26+
if (is.null(value) || is.na(value)) {
27+
return("")
28+
}
29+
value <- as.character(value)
30+
value <- gsub("\\s+", " ", value, perl = TRUE)
31+
value <- gsub("\\s*<[^>]+>", "", value, perl = TRUE)
32+
trimws(value)
33+
}
34+
35+
# Build the package list via utils::installed.packages(), optionally scoped to a
36+
# specific library path (used by the renv method).
37+
.ps.pkg_list_installed <- function(lib.loc = NULL) {
38+
ip <- utils::installed.packages(
39+
lib.loc = lib.loc,
40+
fields = c("Description", "Maintainer")
41+
)
42+
lapply(seq_len(nrow(ip)), function(i) {
43+
list(
44+
id = paste0(ip[i, "Package"], "-", ip[i, "Version"]),
45+
name = ip[i, "Package"],
46+
displayName = ip[i, "Package"],
47+
version = ip[i, "Version"],
48+
description = .ps.pkg_description_text(ip[i, "Description"]),
49+
author = .ps.pkg_author_text(ip[i, "Maintainer"])
50+
)
51+
})
52+
}
53+
1154
# Return a list of installed packages
1255
#' @export
1356
.ps.rpc.pkg_list <- function(method = c("pak", "base", "renv")) {
@@ -23,32 +66,14 @@
2366
id = paste0(pkgs$package[[i]], "-", pkgs$version[[i]]),
2467
name = pkgs$package[[i]],
2568
displayName = pkgs$package[[i]],
26-
version = as.character(pkgs$version[[i]])
69+
version = as.character(pkgs$version[[i]]),
70+
description = .ps.pkg_description_text(pkgs$description[[i]]),
71+
author = .ps.pkg_author_text(pkgs$maintainer[[i]])
2772
)
2873
})
2974
},
30-
base = {
31-
ip <- utils::installed.packages()
32-
lapply(seq_len(nrow(ip)), function(i) {
33-
list(
34-
id = paste0(ip[i, "Package"], "-", ip[i, "Version"]),
35-
name = ip[i, "Package"],
36-
displayName = ip[i, "Package"],
37-
version = ip[i, "Version"]
38-
)
39-
})
40-
},
41-
renv = {
42-
ip <- utils::installed.packages(lib.loc = renv::paths$library())
43-
lapply(seq_len(nrow(ip)), function(i) {
44-
list(
45-
id = paste0(ip[i, "Package"], "-", ip[i, "Version"]),
46-
name = ip[i, "Package"],
47-
displayName = ip[i, "Package"],
48-
version = ip[i, "Version"]
49-
)
50-
})
51-
}
75+
base = .ps.pkg_list_installed(),
76+
renv = .ps.pkg_list_installed(lib.loc = renv::paths$library())
5277
)
5378
}
5479

0 commit comments

Comments
 (0)