Last active
October 8, 2020 12:46
-
-
Save bearloga/7c9078b493e7afb0ca46d5d16bd1aba4 to your computer and use it in GitHub Desktop.
The script can be used to re-install packages after upgrading R (on Linux or Mac), since libraries cannot be reused between different minor versions (e.g. when upgrading 3.2.3 to 3.3.2). It detects when a package was installed from CRAN vs GitHub/Git and re-installs it using the appropriate func. Usage: `Rscript upgrade_packages.R`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# WMF only: | |
if (file.exists("/etc/wikimedia-cluster")) { | |
message('Detected that this script is being run on a WMF machine ("', Sys.info()["nodename"], '"). Setting proxies...') | |
Sys.setenv("http_proxy" = "http://webproxy.eqiad.wmnet:8080") | |
Sys.setenv("https_proxy" = "http://webproxy.eqiad.wmnet:8080") | |
} | |
# General use: | |
message("Checking for a personal library...") | |
if (!dir.exists(Sys.getenv("R_LIBS_USER"))) { | |
warning("Personal library not found, creating one...") | |
dir.create(Sys.getenv("R_LIBS_USER"), recursive = TRUE) | |
message("Registering newly created personal library...") | |
.libPaths(Sys.getenv("R_LIBS_USER")) | |
} else { | |
message("Personal library found.") | |
} | |
message("Installing {remotes} for re-installing from GitHub, etc....") | |
install.packages("remotes", repos = c(CRAN = "https://cran.rstudio.com")) | |
# ^ also ensures that we have a personal library for this version of R | |
if (! "remotes" %in% installed.packages()[, "Package"]) { | |
stop("{remotes} is/was not installed!") | |
} | |
# First, we locate the various personal R libraries the user has: | |
if (Sys.info()["sysname"] == "Linux") { | |
pkg_paths <- dir(paste0(Sys.getenv("HOME"), "/R/", R.version$platform, "-library"), full.names = TRUE) | |
} else if (Sys.info()["sysname"] == "Darwin") { | |
pkg_paths <- file.path(dir("~/Library/R", full.names = TRUE), "library") | |
} | |
# Pick the latest one that is not the current R version's library: | |
pkg_paths <- pkg_paths[!vapply(pkg_paths, function(path) { any(grepl(path, .libPaths(), fixed = TRUE)) }, FALSE)] | |
pkg_path <- tail(pkg_paths, 1) | |
if (length(pkg_path) == 0) { | |
stop("Nothing to do.") | |
} else { | |
message("Found library from previous R installation: ", pkg_path) | |
} | |
# List of installed packages in the user's personal library: | |
installed_pkgs <- dir(pkg_path) | |
if (length(installed_pkgs) == 0) { | |
stop("Did not find any packages from previous R installation.") | |
} | |
message("Found ", length(installed_pkgs), " packages from previous R installation.") | |
# A helper function for extracting a parameter | |
# from an installed package's DESCRIPTION file | |
extract_param <- function(DESCRIPTION, param) { | |
return(sub(paste0(param, ": "), "", DESCRIPTION[grepl(param, DESCRIPTION)], fixed = TRUE)) | |
} | |
message("Extracting metadata about packages from previous R installation...") | |
pkgs_info <- do.call(rbind, lapply(installed_pkgs, function(installed_pkg) { | |
# message('Checking how "', installed_pkg, '" was installed...') | |
pkg_description <- readLines(file.path(find.package(installed_pkg, lib.loc = pkg_path), "DESCRIPTION")) | |
if (any(grepl("Repository: CRAN", pkg_description))) { | |
# message('"', installed_pkg, '" was installed from CRAN.') | |
pkg_source <- "cran"; pkg_url <- NA | |
} else if (any(grepl("Additional_repositories", pkg_description))) { | |
# e.g. {cmdstanr} & {posterior} installed from https://mc-stan.org/r-packages/ (drat) | |
pkg_source <- "other"; pkg_url <- extract_param(pkg_description, "Additional_repositories") | |
} else if (any(grepl("RemoteType", pkg_description))) { | |
# message('"', installed_pkg, '" was installed from a remote source like GitHub.') | |
pkg_source <- extract_param(pkg_description, "RemoteType") | |
if (pkg_source == "github") { | |
pkg_url <- paste(extract_param(pkg_description, "GithubUsername"), extract_param(pkg_description, "GithubRepo"), sep = "/") | |
} else if (pkg_source == "git") { | |
pkg_url <- extract_param(pkg_description, "RemoteUrl") | |
} else { | |
pkg_source <- "other remote"; pkg_url <- NA | |
} | |
} else { | |
# message('"', installed_pkg, '" was installed from a local source.') | |
pkg_source <- "local"; pkg_url <- NA | |
} | |
return(data.frame( | |
package = installed_pkg, | |
source = pkg_source, | |
url = pkg_url, | |
stringsAsFactors = FALSE | |
)) | |
})) | |
# Re-install packages: | |
if (sum(pkgs_info$source == "cran") > 0) { | |
message("Re-installing ", sum(pkgs_info$source == "cran"), " R packages from CRAN...") | |
install.packages(pkgs_info$package[pkgs_info$source == "cran"], repos = c(CRAN = "https://cran.rstudio.com")) | |
} | |
if (sum(pkgs_info$source == "github") > 0) { | |
message("The following ", sum(pkgs_info$source == "github"), " packages will be re-installed from GitHub: ", paste(pkgs_info$package[pkgs_info$source == "github"], collapse = ", ")) | |
remotes::install_github(pkgs_info$url[pkgs_info$source == "github"]) | |
} | |
if (sum(pkgs_info$source == "git") > 0) { | |
message("The following ", sum(pkgs_info$source == "git"), " packages will be re-installed from Git repos: ", paste(pkgs_info$package[pkgs_info$source == "git"], collapse = ", ")) | |
remotes::install_git(pkgs_info$url[pkgs_info$source == "git"]) | |
} | |
if (sum(pkgs_info$source == "other") > 0) { | |
message("The following ", sum(pkgs_info$source == "other"), " packages will be re-installed from other repos: ", paste(pkgs_info$package[pkgs_info$source == "other"], collapse = ", ")) | |
install.packages(pkgs_info$package[pkgs_info$source == "other"], repos = c(CRAN = "https://cran.rstudio.com", pkgs_info$url[pkgs_info$source == "other"])) | |
} | |
if (sum(pkgs_info$source %in% c("other remote", "local")) > 0) { | |
message("The following ", sum(pkgs_info$source %in% c("other remote", "local")), " packages will need to be manually re-installed (sorry): ", paste(pkgs_info$package[pkgs_info$source %in% c("other remote", "local")], collapse = ", ")) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Then re-install the R kernel spec: