Skip to content

Commit cf0c62e

Browse files
committed
Merge branch 'dev'
* dev: Checks if the project looks like an R project and asks for confirmation. #227 Add functionality to force re-installation of all discovered packages and dependencies. #183 Run Travis tests also for NOT_CRAN="false" Test if logfile exists must be skipped on CRAN #225 Add function to list checkpoint archives and remove archives #228
2 parents 35fc713 + 774c8d0 commit cf0c62e

File tree

11 files changed

+179
-28
lines changed

11 files changed

+179
-28
lines changed

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ r:
55

66
sudo: required
77

8-
env: NOT_CRAN="true"
8+
env:
9+
- NOT_CRAN="true"
10+
- NOT_CRAN="false"
911

1012
r_binary_packages:
1113
- testthat

NAMESPACE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Generated by roxygen2: do not edit by hand
22

33
export(checkpoint)
4+
export(checkpointArchives)
5+
export(checkpointRemove)
46
export(getValidSnapshots)
57
export(setSnapshot)
68
importFrom(utils,Stangle)

R/checkpoint.R

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@
5353
#' @param scan.rnw.with.knitr If TRUE, uses \code{\link[knitr]{knit}} to parse \code{.Rnw} files, otherwise use \code{\link[utils]{Sweave}}
5454
#'
5555
#' @param verbose If TRUE, displays progress messages.
56+
#'
57+
#' @param forceInstall If TRUE, forces the re-installation of all discovered packages and their dependencies. This is useful if, for some reason, the checkpoint archive becomes corrupted.
5658
#'
59+
#' @param forceProject If TRUE, forces the checkpoint process, even if the provided project folder doesn't look like an R project. A commonly reported user problem is that they accidentally trigger the checkpoint process from their home folder, resulting in scanning many R files and downloading many packages. To prevent this, we use a heuristic to determine if the project folder looks like an R project. If the project folder is the home folder, and also contains no R files, then \code{checkpoint()} asks for confirmation to continue.
60+
5761
#'
5862
#' @return Checkpoint is called for its side-effects (see the details section), but invisibly returns a list with elements:
5963
#' \itemize{
@@ -75,7 +79,11 @@ checkpoint <- function(snapshotDate, project = getwd(), R.version, scanForPackag
7579
verbose=TRUE,
7680
use.knitr = system.file(package="knitr") != "",
7781
auto.install.knitr = TRUE,
78-
scan.rnw.with.knitr = FALSE) {
82+
scan.rnw.with.knitr = FALSE,
83+
forceInstall = FALSE,
84+
forceProject = FALSE) {
85+
86+
if(interactive()) validateProjectFolder(project)
7987

8088
stopIfInvalidDate(snapshotDate)
8189

@@ -135,8 +143,20 @@ checkpoint <- function(snapshotDate, project = getwd(), R.version, scanForPackag
135143
files.not.parsed <- character(0)
136144
}
137145

138-
139-
packages.to.install <- setdiff(packages.detected, c(packages.installed, exclude.packages))
146+
if(forceInstall && packages.detected > 0){
147+
to_remove <- as.vector(unlist(tools::package_dependencies(packages.detected)))
148+
to_remove <- c(packages.detected, to_remove)
149+
tryCatch(
150+
suppressMessages(suppressWarnings(
151+
utils::remove.packages(to_remove)
152+
)),
153+
error = function(e)e
154+
)
155+
packages.to.install <- packages.detected
156+
packages.installed <- character(0)
157+
} else {
158+
packages.to.install <- setdiff(packages.detected, c(packages.installed, exclude.packages))
159+
}
140160

141161
# detach checkpointed pkgs already loaded
142162

@@ -174,16 +194,16 @@ checkpoint <- function(snapshotDate, project = getwd(), R.version, scanForPackag
174194
INSTALL_opts = "--no-lock")
175195
)
176196
}, type = "message")
177-
}
178-
checkpoint_log(
179-
download_messages,
180-
snapshotDate = snapshotDate,
181-
pkg,
182-
file = file.path(
183-
checkpointPath(snapshotDate, checkpointLocation, type = "root"),
184-
"checkpoint_log.csv")
197+
checkpoint_log(
198+
download_messages,
199+
snapshotDate = snapshotDate,
200+
pkg,
201+
file = file.path(
202+
checkpointPath(snapshotDate, checkpointLocation, type = "root"),
203+
"checkpoint_log.csv")
185204
)
186-
205+
}
206+
187207
}
188208
} else if(length(packages.detected > 0)){
189209
mssg(verbose, "All detected packages already installed")
@@ -225,3 +245,28 @@ mssg <- function(x, ...) if(x) message(...)
225245

226246
correctR <- function(x) compareVersion(as.character(utils::packageVersion("base")), x) == 0
227247

248+
249+
# Scans for R files in a folder and the first level subfolders.
250+
#
251+
anyRfiles <- function(path = "."){
252+
findRfiles <- function(path = "."){
253+
pattern <- "\\.[rR]$|\\.[rR]nw$|\\.[rR]md$|\\.[rR]pres$|\\.[rR]proj$"
254+
z <- list.files(path = path, pattern = pattern, full.names = TRUE)
255+
normalizePath(z, winslash = "/")
256+
}
257+
dirs <- list.dirs(path = path, recursive = FALSE)
258+
rfiles <- as.vector(unlist(sapply(dirs, findRfiles)))
259+
length(rfiles) > 0
260+
}
261+
262+
validateProjectFolder <- function(project) {
263+
if(normalizePath(project) == normalizePath("~/") && !anyRfiles(project)){
264+
message("This doesn't look like an R project directory.\n",
265+
"Use forceProject = TRUE to force scanning"
266+
)
267+
answer = readline("Continue (y/n)? ")
268+
if(tolower(answer) != "y"){
269+
stop("Scanning stopped.", call. = FALSE)
270+
}
271+
}
272+
}

R/checkpoint_paths.R

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ authorizeFileSystemUse =
4444
stop("Can't use a non-directory as checkpoint root")}
4545
else {
4646
if(interactive()) {
47-
answer = readline(paste("Can I create directory", checkpointRoot, "for internal checkpoint use?(y/n)\n"))
47+
message(paste("Can I create directory", checkpointRoot, "for internal checkpoint use?\n"))
48+
answer = readline("Continue (y/n)? ")
4849
if(tolower(answer) != "y")
4950
stop("Cannot proceed without access to checkpoint directory")}
5051
else {

R/checkpoint_remove.R

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
3+
#' List checkpoint archives on disk.
4+
#'
5+
#' @inheritParams checkpoint
6+
#' @export
7+
#' @seealso checkpointRemove
8+
#' @example inst/examples/example_remove.R
9+
checkpointArchives <- function(checkpointLocation = "~/"){
10+
z <- list.files(path = paste0(normalizePath(checkpointLocation), ".checkpoint"),
11+
pattern = "\\d{4}-\\d{2}-\\d{2}",
12+
full.names = TRUE)
13+
normalizePath(z, winslash = "/")
14+
}
15+
16+
#' Remove checkpoint archive from disk.
17+
#'
18+
#' @inheritParams checkpoint
19+
#' @export
20+
#' @seealso checkpointArchives
21+
#' @example inst/examples/example_remove.R
22+
checkpointRemove <- function(snapshotDate, checkpointLocation = "~/"){
23+
z <- list.files(path = paste0(normalizePath(checkpointLocation), ".checkpoint"),
24+
pattern = paste0(snapshotDate, "$"),
25+
full.names = TRUE)
26+
to_delete <- normalizePath(z, winslash = "/")
27+
if(length(to_delete) == 0) {
28+
warning("archive not found")
29+
invisible(NULL)
30+
} else {
31+
res <- unlink(to_delete, recursive = TRUE)
32+
if(res == 0) message("successfully removed archive")
33+
}
34+
}
35+
36+

R/mranUrl.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ setCheckpointUrl <- function(url){
107107

108108

109109
tryUrl <- function(url){
110-
con <- tryCatch(url(url), error = function(e)e)
110+
con <- suppressWarnings(tryCatch(url(url), error = function(e)e))
111111
msg <- paste0(
112112
"Invalid value for mranRootUrl.\n",
113113
"Ensure you use the correct http://, https:// or file:/// prefix."
@@ -129,7 +129,7 @@ getValidSnapshots <- function(mranRootUrl = mranUrl()){
129129
text <- if (inherits(con, "file")) {
130130
dir(summary(con)$description)
131131
} else {
132-
tryCatch(readLines(con, warn = TRUE), error = function(e) e)
132+
suppressWarnings(tryCatch(readLines(con, warn = TRUE), error = function(e) e))
133133
}
134134
if (inherits(text, "error")) {
135135
stop(sprintf("Unable to download from MRAN: %s",

inst/examples/example_remove.R

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
checkpointArchives()
2+
\dontrun{
3+
checkpointRemove("2016-10-01")
4+
}
5+

man/checkpoint.Rd

Lines changed: 6 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/checkpointArchives.Rd

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/checkpointRemove.Rd

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)