-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathinstall_github.R
More file actions
125 lines (108 loc) · 4.83 KB
/
install_github.R
File metadata and controls
125 lines (108 loc) · 4.83 KB
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#' install_github installs R packages directly from GitHub
#'
#' install_github is a very lightweight function with no dependencies
#' that installs R packages from GitHub.
#'
#' @param repo identifies the GitHub repository, i.e. username/repo. Also flexibly
#' accepts arguments of the form username/repo@branch.
#' @param branch identifies the branch (optional)
#' @param dependencies is a vector that indicates which type of additional
#' packages are also to be installed. It can include any of the values in
#' \code{c("Depends", "Imports", "LinkingTo", "Suggests", "Enhances")}. A
#' value of \code{TRUE} corresponds to \code{c("Depends", "Imports",
#' "LinkingTo")}. If \code{dependencies} equals \code{FALSE} no further
#' packages will be installed.
#' @param method specifies which method \code{download.file} uses to download
#' the zip archive from GitHub. Can be set to any of the values in
#' \code{c("auto", "wget", "libcurl", "curl", "wininet")}. When set to
#' \code{auto}, this function will make an educated guess.
#' @examples
#' \dontrun{install_github("jtilly/matchingR")}
install_github = function(repo,
branch = if (grepl("@", repo)) gsub(".*@", "", repo) else "master",
dependencies = TRUE, method = "auto") {
if (getRversion() < "3.2.0") {
trimws = function (x, which = c("both", "left", "right")) {
which = match.arg(which)
mysub = function(re, x) sub(re, "", x, perl = TRUE)
if (which == "left")
return(mysub("^[ \\t\\r\\n]+", x))
if (which == "right")
return(mysub("[ \\t\\r\\n]+$", x))
mysub("[ \\t\\r\\n]+$", mysub("^[ \\t\\r\\n]+", x))
}
}
# unix system?
unix = Sys.info()["sysname"] %in% c("Darwin", "Linux")
# select a method to download files over https
if(method == "auto") {
if(unix) {
if(file.exists(Sys.which("libcurl"))) {
method = "libcurl"
} else if (file.exists(Sys.which("wget"))) {
method = "wget"
} else if (file.exists(Sys.which("curl"))) {
method = "curl"
} else {
stop("Could not find method to download files over https.")
}
} else {
# there's probably a way to fix this...
if(getRversion() < "3.2") {
stop("Need R 3.2 or higher to download files over https.")
}
method = "wininet"
}
}
# assemble URL
url = paste0("https://github.com/", gsub("@.*", "", repo), "/archive/", branch, ".zip")
# create a temporary directory
tmpdir = tempdir()
pkg.zip = file.path(tmpdir, paste0(branch, ".zip"))
# download the zip archive from GitHub
message("Downloading ", url, " using ", method)
# follow redirects with curl requires passing in the -L option
download.file(url = url, destfile = pkg.zip,
method = method,
extra = if (method == "curl") "-L" else getOption("download.file.extra"))
message("Saved as ", pkg.zip)
if (!file.exists(pkg.zip)) {
stop("Download failed.")
}
# extract the archive
pkg.root = file.path(tmpdir, branch)
unzip(pkg.zip, overwrite = TRUE, exdir = pkg.root)
message("Extracted package to ", pkg.root)
# assemble path to downloaded package
pkg.dir = file.path(pkg.root, list.files(pkg.root)[1])
# default dependencies
if (isTRUE(dependencies)) {
dependencies = c("Depends", "Imports", "LinkingTo")
}
# Get dependencies from the package's DESCRIPTION
if(!is.null(dependencies)) {
# http://stackoverflow.com/questions/30223957/elegantly-extract-r-package-dependencies-of-a-package-not-listed-on-cran
dcf = read.dcf(file.path(pkg.dir, "DESCRIPTION"))
deps = unique(gsub("\\s.*", "", trimws(unlist(strsplit(dcf[, intersect(dependencies, colnames(dcf))], ","), use.names = FALSE))))
# install dependencies that aren't already installed
deps = deps[!(deps %in% c("R", rownames(installed.packages())))]
if(length(deps)) {
message("Also installing: ", paste(deps))
install.packages(deps)
}
}
# check if the package has a configure / cleanup script and set
# chmod on unix type systems
if (unix) {
for(script in c("configure", "cleanup")) {
if (file.exists(file.path(pkg.dir, script))) {
Sys.chmod(file.path(pkg.dir, script), mode = "0755", use_umask = TRUE)
}
}
}
# install the package
install.packages(pkg.dir, repos = NULL, type = "source")
# clean up
unlink(pkg.root, recursive = TRUE, force = TRUE)
unlink(pkg.zip, force = TRUE)
}