-
Notifications
You must be signed in to change notification settings - Fork 29
Add pkg_detail RPC for packages pane detail editor #1291
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
d1fa7d9
05a39e4
aea6989
62a9176
3e986e4
161f556
9584e5f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -115,6 +115,104 @@ | |
| as.list(version) | ||
| } | ||
|
|
||
| # Return detail fields for a single installed package by name. | ||
| #' @export | ||
| .ps.rpc.pkg_detail <- function(name) { | ||
| installed <- rownames(utils::installed.packages()) | ||
| if (!nzchar(name) || !(name %in% installed)) { | ||
| return(NULL) | ||
| } | ||
| fields <- c( | ||
| "Title", | ||
| "Author", | ||
| "Maintainer", | ||
| "License", | ||
| "Depends", | ||
| "Imports", | ||
| "LinkingTo", | ||
| "Repository", | ||
| "Date/Publication" | ||
| ) | ||
| d <- utils::packageDescription(name, fields = fields) | ||
|
|
||
| # Collapse DCF whitespace; return NULL for missing (NA) fields. | ||
| clean <- function(x) { | ||
| if (is.null(x) || is.na(x)) { | ||
| return(NULL) | ||
| } | ||
| trimws(gsub("\\s+", " ", x, perl = TRUE)) | ||
| } | ||
|
|
||
| # Parse a comma-separated dependency field into bare package names | ||
| # (strip version constraints like "(>= 1.0)"). | ||
| parse_deps <- function(x) { | ||
| if (is.null(x) || is.na(x)) { | ||
| return(character(0)) | ||
| } | ||
| parts <- trimws(strsplit(x, ",")[[1]]) | ||
| names <- trimws(sub("\\(.*\\)", "", parts)) | ||
| names[nzchar(names)] | ||
| } | ||
|
|
||
| # Reduce an R License field to its primary license: the first alternative | ||
| # (before "|"), without the "+ file LICENSE" clause. | ||
| primary_license <- function(x) { | ||
| if (is.null(x)) { | ||
| return(NULL) | ||
| } | ||
| first <- trimws(strsplit(x, "\\|")[[1]][1]) | ||
| first <- trimws(sub( | ||
| "\\s*\\+\\s*file\\s+.*$", | ||
| "", | ||
| first, | ||
| ignore.case = TRUE | ||
| )) | ||
| if (!nzchar(first)) { | ||
| return(NULL) | ||
| } | ||
| first | ||
| } | ||
|
|
||
| base_pkgs <- rownames(utils::installed.packages(priority = "base")) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given the downsides to calling If you really want to compute it, I'd suggest: |
||
| deps <- unique(c( | ||
| parse_deps(d$Depends), | ||
| parse_deps(d$Imports), | ||
| parse_deps(d$LinkingTo) | ||
| )) | ||
| deps <- setdiff(deps, c("R", base_pkgs)) | ||
|
|
||
| out <- list(name = name, dependencyCount = length(deps)) | ||
|
|
||
| # Prefer Maintainer for author display; fall back to Author. | ||
| author <- clean(d$Maintainer) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW a CRAN package absolutely must have a Maintainer. But I suppose this pane could populate from a non-CRAN source? Just thought I'd mention. |
||
| if (is.null(author)) { | ||
| author <- clean(d$Author) | ||
| } | ||
| title <- clean(d$Title) | ||
| license <- primary_license(clean(d$License)) | ||
| repo <- clean(d$Repository) | ||
| published <- clean(d[["Date/Publication"]]) | ||
|
|
||
| if (!is.null(title)) { | ||
| out$title <- title | ||
| } | ||
| if (!is.null(author)) { | ||
| out$author <- author | ||
| } | ||
| if (!is.null(license)) { | ||
| out$license <- license | ||
| } | ||
| if (!is.null(repo)) { | ||
| out$sourceRepository <- repo | ||
| } | ||
| if (!is.null(published)) { | ||
| out$publishedDate <- published | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you definitely want to drop the out <- list(
name = name,
title = title,
author = author,
license = license,
sourceRepository = repo,
publishedDate = published
)
Filter(Negate(is.null), out) |
||
| } | ||
|
|
||
| out | ||
| } | ||
|
|
||
|
|
||
| # Return the list of outdated packages with their latest available versions. | ||
| # | ||
| # `utils::old.packages()` queries the user's configured repositories, so | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will be more efficient to just go directly to
utils::packageDescription(), which will returnNAif the package is not installed. This avoids reading and parsing DESCRIPTION of all installed packages for this existence check.installed.packages()docs say: