Skip to content

Commit 7f3ded2

Browse files
committed
wire in support for subdirs (#129)
1 parent 16464b7 commit 7f3ded2

File tree

8 files changed

+115
-19
lines changed

8 files changed

+115
-19
lines changed

DESCRIPTION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package: renv
22
Type: Package
33
Title: Project Environments for R
4-
Version: 0.6.0-63
4+
Version: 0.6.0-64
55
Authors@R: c(
66
person("Kevin", "Ushey", role = c("aut", "cre"), email = "[email protected]"),
77
person("RStudio", role = c("cph"))

R/description.R

+11-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
renv_description_read <- function(path = NULL, package = NULL, ...) {
2+
renv_description_read <- function(path = NULL, package = NULL, subdir = "", ...) {
33

44
# if given a package name, construct path to that package
55
if (!is.null(package))
@@ -32,11 +32,18 @@ renv_description_read <- function(path = NULL, package = NULL, ...) {
3232
# find the DESCRIPTION file. note that for some source tarballs (e.g.
3333
# those from GitHub) the first entry may not be the package name, so
3434
# just consume everything up to the first slash
35-
file <- grep("^[^/]+/DESCRIPTION$", files, value = TRUE)
36-
if (length(file) != 1)
37-
stopf("failed to infer path to DESCRIPTION within file '%s'", path)
35+
parts <- c(if(nzchar(subdir)) subdir, "DESCRIPTION$")
36+
descpath <- paste(parts, collapse = "/")
37+
pattern <- paste0("(?:^|/)", descpath)
38+
39+
descs <- grep(pattern, files, value = TRUE)
40+
if (empty(descs)) {
41+
fmt <- "archive '%s' does not appear to contain a DESCRIPTION file"
42+
stopf(fmt, aliased_path(path))
43+
}
3844

3945
# unpack into tempdir location
46+
file <- descs[[1]]
4047
exdir <- renv_tempfile("renv-description-")
4148
renv_archive_decompress(path, files = file, exdir = exdir)
4249

R/install.R

+22-2
Original file line numberDiff line numberDiff line change
@@ -226,15 +226,35 @@ renv_install_package_local <- function(record, quiet = TRUE) {
226226
# get user-defined options to apply during installation
227227
options <- renv_install_package_options(package)
228228

229+
# get archive path for package
230+
library <- renv_libpaths_default()
231+
path <- record$Path
232+
233+
# for packages living within a sub-directory, we need to
234+
# unpack the archive explicitly and update the path
235+
subdir <- record$RemoteSubdir %||% ""
236+
if (nzchar(subdir)) {
237+
238+
# create extraction directory
239+
dir <- tempfile("renv-package-")
240+
ensure_directory(dir)
241+
on.exit(unlink(dir, recursive = TRUE), add = TRUE)
242+
243+
# decompress archive to dir
244+
renv_archive_decompress(path, exdir = dir)
245+
246+
# update path
247+
path <- file.path(dir, list.files(dir)[[1]], subdir)
248+
249+
}
250+
229251
# run user-defined hooks before, after install
230252
before <- options$before.install %||% identity
231253
after <- options$after.install %||% identity
232254

233255
before(package)
234256
on.exit(after(package), add = TRUE)
235257

236-
library <- renv_libpaths_default()
237-
path <- record$Path
238258

239259
destination <- file.path(library, package)
240260
callback <- renv_file_backup(destination)

R/remotes.R

+16-9
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ renv_remotes_resolve_github_sha_pull <- function(host, user, repo, pull) {
128128

129129
fmt <- "https://%s/repos/%s/%s/pulls/%s"
130130
url <- sprintf(fmt, host, user, repo, pull)
131-
jsonfile <- renv_tempfile("ren-json-")
131+
jsonfile <- renv_tempfile("renv-json-")
132132
download(url, destfile = jsonfile, type = "github", quiet = TRUE)
133133
json <- renv_json_read(jsonfile)
134134
json$head$sha
@@ -154,11 +154,15 @@ renv_remotes_resolve_github_sha_ref <- function(host, user, repo, ref) {
154154

155155
}
156156

157-
renv_remotes_resolve_github_description <- function(host, user, repo, sha) {
157+
renv_remotes_resolve_github_description <- function(host, user, repo, subdir, sha) {
158+
159+
# form DESCRIPTION path
160+
parts <- c(if (nzchar(subdir)) subdir, "DESCRIPTION")
161+
descpath <- paste(parts, collapse = "/")
158162

159163
# get the DESCRIPTION contents
160-
fmt <- "https://%s/repos/%s/%s/contents/DESCRIPTION?ref=%s"
161-
url <- sprintf(fmt, host, user, repo, sha)
164+
fmt <- "https://%s/repos/%s/%s/contents/%s?ref=%s"
165+
url <- sprintf(fmt, host, user, repo, descpath, sha)
162166
jsonfile <- renv_tempfile("renv-json-")
163167
download(url, destfile = jsonfile, type = "github", quiet = TRUE)
164168
json <- renv_json_read(jsonfile)
@@ -188,7 +192,7 @@ renv_remotes_resolve_github <- function(entry) {
188192
nzchar(ref) ~ renv_remotes_resolve_github_sha_ref(host, user, repo, ref)
189193
)
190194

191-
desc <- renv_remotes_resolve_github_description(host, user, repo, sha)
195+
desc <- renv_remotes_resolve_github_description(host, user, repo, subdir, sha)
192196

193197
list(
194198
Package = desc$Package,
@@ -211,10 +215,13 @@ renv_remotes_resolve_gitlab <- function(entry) {
211215
subdir <- entry$subdir
212216
ref <- entry$ref %""% "master"
213217

214-
fmt <- "https://%s/api/v4/projects/%s/repository/files/DESCRIPTION/raw?ref=%s"
218+
parts <- c(if (nzchar(subdir)) subdir, "DESCRIPTION")
219+
descpath <- URLencode(paste(parts, collapse = "/"), reserved = TRUE)
220+
221+
fmt <- "https://%s/api/v4/projects/%s/repository/files/%s/raw?ref=%s"
215222
host <- renv_config("gitlab.host", "gitlab.com")
216-
id <- paste(user, repo, sep = "%2F")
217-
url <- sprintf(fmt, host, id, ref)
223+
id <- URLencode(paste(user, repo, sep = "/"), reserved = TRUE)
224+
url <- sprintf(fmt, host, id, descpath, ref)
218225

219226
destfile <- renv_tempfile("renv-description-")
220227
download(url, destfile = destfile, type = "gitlab", quiet = TRUE)
@@ -223,7 +230,7 @@ renv_remotes_resolve_gitlab <- function(entry) {
223230
list(
224231
Package = desc$Package,
225232
Version = desc$Version,
226-
Source = "Gitlab",
233+
Source = "GitLab",
227234
RemoteUsername = user,
228235
RemoteRepo = repo,
229236
RemoteSubdir = subdir,

R/retrieve.R

+9-2
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,10 @@ renv_retrieve_gitlab <- function(record) {
170170

171171
# TODO: remotes doesn't appear to understand how to interact with GitLab API?
172172
host <- record$RemoteHost %||% "gitlab.com"
173-
id <- paste(record$RemoteUsername, record$RemoteRepo, sep = "%2F")
173+
174+
user <- record$RemoteUsername
175+
repo <- record$RemoteRepo
176+
id <- URLencode(paste(user, repo, sep = "/"), reserved = TRUE)
174177

175178
fmt <- "https://%s/api/v4/projects/%s/repository/archive.tar.gz"
176179
url <- sprintf(fmt, host, id)
@@ -424,7 +427,11 @@ renv_retrieve_package <- function(record, url, path) {
424427
renv_retrieve_successful <- function(record, path, install = TRUE) {
425428

426429
# augment record with information from DESCRIPTION file
427-
desc <- renv_description_read(path)
430+
subdir <- record$RemoteSubdir %||% ""
431+
desc <- renv_description_read(path, subdir = subdir)
432+
433+
# update the record's package name, version
434+
# TODO: should we warn if they didn't match for some reason?
428435
record$Package <- desc$Package
429436
record$Version <- desc$Version
430437

tests/testthat/test-install.R

+38
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,41 @@ test_that("packages can be installed from local sources", {
7676
expect_true(renv_package_version("bread") == "1.0.0")
7777

7878
})
79+
80+
test_that("various remote styles can be used during install", {
81+
skip_on_cran()
82+
83+
renv_tests_scope()
84+
renv::init()
85+
86+
# install CRAN latest
87+
renv::install("bread")
88+
expect_true(renv_package_installed("bread"))
89+
expect_true(renv_package_version("bread") == "1.0.0")
90+
91+
# install from archive
92+
renv::install("[email protected]")
93+
expect_true(renv_package_installed("bread"))
94+
expect_true(renv_package_version("bread") == "0.1.0")
95+
96+
# install from github
97+
renv::install("kevinushey/skeleton")
98+
expect_true(renv_package_installed("skeleton"))
99+
expect_true(renv_package_version("skeleton") == "1.0.1")
100+
101+
# install from github PR
102+
renv::install("kevinushey/skeleton#1")
103+
expect_true(renv_package_installed("skeleton"))
104+
expect_true(renv_package_version("skeleton") == "1.0.2")
105+
106+
# install from branch
107+
renv::install("kevinushey/skeleton@feature/version-bump")
108+
expect_true(renv_package_installed("skeleton"))
109+
expect_true(renv_package_version("skeleton") == "1.0.2")
110+
111+
#install from subdir
112+
renv::install("kevinushey/subdir/subdir")
113+
expect_true(renv_package_installed("subdir"))
114+
expect_true(renv_package_version("subdir") == "0.0.0.9000")
115+
116+
})

tests/testthat/test-retrieve.R

+17
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,23 @@ test_that("we can retrieve packages from GitHub", {
7878

7979
})
8080

81+
test_that("we can retrieve packages from GitHub (in a sub-directory)", {
82+
skip_on_cran()
83+
skip_if_offline(host = "github.com")
84+
85+
record <- list(
86+
Package = "subdir",
87+
Source = "github",
88+
RemoteUsername = "kevinushey",
89+
RemoteRepo = "subdir",
90+
RemoteSubdir = "subdir",
91+
RemoteSha = "100373b23c8adae1da4e4d6995402d40e9227cfb"
92+
)
93+
94+
renv_test_retrieve(record)
95+
96+
})
97+
8198

8299
test_that("we can retrieve packages from GitLab", {
83100
skip_on_cran()

vignettes/renv.Rmd

+1-1
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ required authentication information.
231231
| **Remote Source** | **Authentication** |
232232
| ----------------- | --------------------------------------- |
233233
| GitHub | `GITHUB_PAT` |
234-
| Gitlab | `GITLAB_PAT` |
234+
| GitLab | `GITLAB_PAT` |
235235
| Bitbucket | `BITBUCKET_USER` + `BITBUCKET_PASSWORD` |
236236
| Git Remotes | `GIT_PAT` / `GIT_USER` + `GIT_PASSWORD` |
237237

0 commit comments

Comments
 (0)