Skip to content
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

installPkg: do no work when using cached package and annotate safely #726

Merged
merged 11 commits into from
Jan 3, 2024
46 changes: 16 additions & 30 deletions R/restore.R
Original file line number Diff line number Diff line change
Expand Up @@ -391,16 +391,10 @@ annotatePkgDesc <- function(pkgRecord, project, lib = libDir(project)) {
content[name] <- records[name]
}

# Write it out
write_dcf(content, descFile)
}

# Annotate a set of packages by name.
annotatePkgs <- function(pkgNames, project, lib = libDir(project)) {
records <- searchPackages(lockInfo(project), pkgNames)
lapply(records, function(record) {
annotatePkgDesc(record, project, lib)
})
# Write it out using a temporary file so DESCRIPTION is never partial.
tmpf <- tempfile(tmpdir = dirname(descFile))
write_dcf(content, tmpf)
file.rename(tmpf, descFile)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this will emit a warning and return false on failure -- do we need to handle that scenario?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. I had dismissed the need to handle the error because the directory is known to be writable and we are not performing a cross-file-system move, but it's probably worth checking the return value.

}

# Takes a vector of package names, and returns a logical vector that indicates
Expand Down Expand Up @@ -433,10 +427,6 @@ installPkg <- function(pkgRecord,
repos,
lib = libDir(project))
{
pkgSrc <- NULL
type <- "built source"
needsInstall <- TRUE

# If we're trying to install a package that overwrites a symlink, e.g. for a
# cached package, we need to move that symlink out of the way (otherwise
# `install.packages()` or `R CMD INSTALL` will fail with surprising errors,
Expand All @@ -451,7 +441,6 @@ installPkg <- function(pkgRecord,
# NOTE: a symlink that points to a path that doesn't exist
# will return FALSE when queried by `file.exists()`!
if (file.exists(pkgInstallPath) || is.symlink(pkgInstallPath)) {

temp <- tempfile(tmpdir = lib)
file.rename(pkgInstallPath, temp)
on.exit({
Expand All @@ -467,23 +456,21 @@ installPkg <- function(pkgRecord,
cacheCopyStatus <- new.env(parent = emptyenv())
copiedFromCache <- restoreWithCopyFromCache(project, pkgRecord, cacheCopyStatus)
if (copiedFromCache) {
type <- cacheCopyStatus$type
needsInstall <- FALSE
return(cacheCopyStatus$type)
}

# Try restoring the package from the 'unsafe' cache, if applicable.
copiedFromUntrustedCache <- restoreWithCopyFromUntrustedCache(project, pkgRecord, cacheCopyStatus)
if (copiedFromUntrustedCache) {
type <- cacheCopyStatus$type
needsInstall <- FALSE
return(cacheCopyStatus$type)
}

# if we still need to attempt an installation at this point,
# remove a prior installation / file from library (if necessary).
# we move the old directory out of the way temporarily, and then
# The package was not in a cache and needs to be installed.
# Remove a prior installation / file from library (if necessary).
# We move the old directory out of the way temporarily, and then
# delete if if all went well, or restore it if installation failed
# for some reason
if (needsInstall && file.exists(pkgInstallPath)) {
# for some reason.
if (file.exists(pkgInstallPath)) {
pkgRenamePath <- tempfile(tmpdir = lib)
file.rename(pkgInstallPath, pkgRenamePath)
on.exit({
Expand All @@ -494,9 +481,11 @@ installPkg <- function(pkgRecord,
}, add = TRUE)
}

type <- "built source"
needsInstall <- TRUE

# Try downloading a binary (when appropriate).
if (!(copiedFromCache || copiedFromUntrustedCache) &&
hasBinaryRepositories() &&
if (hasBinaryRepositories() &&
binaryRepositoriesEnabled() &&
isFromCranlikeRepo(pkgRecord, repos) &&
pkgRecord$name %in% availablePackagesBinary(repos = repos)[, "Package"] &&
Expand Down Expand Up @@ -531,14 +520,11 @@ installPkg <- function(pkgRecord,
})
}

if (is.null(pkgSrc)) {
if (needsInstall) {
# When installing from github/bitbucket/gitlab or an older version, use the cached source
# tarball or zip created in snapshotSources
pkgSrc <- file.path(srcDir(project), pkgRecord$name,
pkgSrcFilename(pkgRecord))
}

if (needsInstall) {

if (!file.exists(pkgSrc)) {
# If the source file is missing, try to download it. (Could happen in the
Expand Down
29 changes: 29 additions & 0 deletions tests/testthat/test-restore.R
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,32 @@ test_that("appendRemoteInfoToDescription modifies DESCRIPTION file", {
expect_identical(tail(desc, 6), expected_desc_tail)
getwd()
})

test_that("annotatePkgDesc annotates a package description", {
project <- tempfile()
dir.create(project)
lib <- libDir(project)
package <- file.path(lib, "fake")
dir.create(package, recursive = TRUE)
desc <- file.path(package, "DESCRIPTION")
write_dcf(
list(
Package = "fake",
Version = "1.2.3",
InstallAgent = "testthat"
),
desc
)
pkgRecord <- list(
name = "fake",
source = "CRAN",
version = "1.2.3"
)

annotatePkgDesc(pkgRecord, project)
result <- as.data.frame(readDcf(desc))
expect_equal(result$Package, "fake")
expect_equal(result$Version, "1.2.3")
expect_equal(result$InstallAgent, paste('packrat', packageVersion('packrat')))
expect_equal(result$InstallSource, "CRAN")
})
Loading