Skip to content

Commit 5fabdac

Browse files
committed
Merge branch 'release'
2 parents 055aad4 + e30e490 commit 5fabdac

File tree

10 files changed

+205
-67
lines changed

10 files changed

+205
-67
lines changed

.travis.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
language: c
2+
3+
before_install:
4+
- curl -OL http://raw.github.com/craigcitro/r-travis/master/scripts/travis-tool.sh
5+
- chmod 755 ./travis-tool.sh
6+
- ./travis-tool.sh bootstrap
7+
8+
install:
9+
- ./travis-tool.sh install_deps
10+
11+
script: ./travis-tool.sh run_tests
12+
13+
on_failure:
14+
- ./travis-tool.sh dump_logs
15+
16+
branches:
17+
only:
18+
- master
19+
- release
20+
- dev
21+
22+
notifications:
23+
email:
24+
on_success: change
25+
on_failure: change

DESCRIPTION

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,16 @@ Description: The goal of checkpoint is to solve the problem of package
1616
Immediately after completion of the rsync mirror process, we take a
1717
snapshot, thus creating the archive. Snapshot archives exist starting from
1818
2014-09-17.
19-
Version: 0.3.6
20-
Date: 2015-01-27
19+
Version: 0.3.7
20+
Date: 2015-02-02
2121
Author: Revolution Analytics
2222
Maintainer: Andrie de Vries <[email protected]>
2323
Copyright: Revolution Analytics
2424
License: GPL-2
2525
URL: http://projects.revolutionanalytics.com/documents/rrt/rrtpkgs/
2626
BugReports: http://www.github.com/RevolutionAnalytics/checkpoint/issues
27+
Imports:
28+
utils
2729
Depends:
2830
R(>= 3.1.1)
2931
Suggests:

NAMESPACE

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
# Generated by roxygen2 (4.0.2): do not edit by hand
1+
# Generated by roxygen2 (4.1.0): do not edit by hand
22

33
export(checkpoint)
4+
importFrom(utils,install.packages)

R/checkpoint.R

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#' @param snapshotDate Date of snapshot to use in \code{YYYY-MM-DD} format,e.g. \code{"2014-09-17"}. Specify a date on or after \code{"2014-09-17"}. MRAN takes one snapshot per day.
2323
#'
2424
#' @param project A project path. This is the path to the root of the project that references the packages to be installed from the MRAN snapshot for the date specified for \code{snapshotDate}. Defaults to current working directory using \code{\link{getwd}()}.
25+
#'
26+
#' @param R.version Optional character string, e.g. "3.1.2". If specified, compares the current R.version to the specified R.version, and warns if these are different. This argument allows the original script author to specify a specific version of R to obtain the desired results.
2527
#'
2628
#' @param use.knitr If TRUE, uses parses all \code{Rmarkdown} files using the \code{knitr} package.
2729
#'
@@ -34,12 +36,23 @@
3436
#'
3537
#' @example /inst/examples/example_checkpoint.R
3638
#'
39+
#' @importFrom utils install.packages
3740

38-
checkpoint <- function(snapshotDate, project = getwd(), verbose=TRUE, use.knitr = system.file(package="knitr") != "") {
41+
checkpoint <- function(snapshotDate, project = getwd(), R.version,
42+
verbose=TRUE,
43+
use.knitr = system.file(package="knitr") != "") {
3944

40-
if(use.knitr) {
41-
if(!require("knitr")) warning("The knitr package is not available and Rmarkdown files will not be parsed")
45+
if(!missing("R.version") && !is.null(R.version)){
46+
if(!correctR(as.character(R.version))){
47+
message <- sprintf("Specified R.version %s does not match current R (%s)",
48+
R.version, utils::packageVersion("base"))
49+
mssg(verbose, message)
50+
mssg(verbose, "Terminating checkpoint")
51+
mssg(verbose, "---")
52+
stop(message)
53+
}
4254
}
55+
4356
createFolders(snapshotDate)
4457
snapshoturl <- getSnapshotUrl(snapshotDate=snapshotDate)
4558

@@ -55,19 +68,29 @@ checkpoint <- function(snapshotDate, project = getwd(), verbose=TRUE, use.knitr
5568
dir.create(file.path(.libPaths(), "compiler"), showWarnings = FALSE)
5669
file.copy(to = .libPaths(), from = compiler.path, recursive = TRUE)
5770
} else {
58-
install.packages(repos = NULL, pkgs = compiler.path, type = "source")
71+
if(! "compiler" %in% installed.packages()[, "Package"]) {
72+
install.packages(repos = NULL, pkgs = compiler.path, type = "source")
73+
}
5974
}
6075

61-
mssg(verbose, "Scanning for loaded pkgs")
62-
6376
# Scan for packages used
6477
mssg(verbose, "Scanning for packages used in this project")
6578
exclude.packages = c("checkpoint", # this very package
6679
c("base", "compiler", "datasets", "graphics", "grDevices", "grid",
6780
"methods", "parallel", "splines", "stats", "stats4", "tcltk",
6881
"tools", "utils")) # all base priority packages, not on CRAN or MRAN
6982
packages.installed <- unname(installed.packages()[, "Package"])
70-
packages.detected <- projectScanPackages(project, use.knitr = use.knitr)
83+
84+
pkgs <- projectScanPackages(project, use.knitr = use.knitr)
85+
packages.detected <- pkgs[["pkgs"]]
86+
87+
mssg(verbose, "- Discovered ", length(packages.detected), " packages")
88+
89+
if(length(pkgs[["error"]]) > 0){
90+
mssg(verbose, "Unable to parse ", length(pkgs[["error"]]), " files:")
91+
for(file in pkgs[["error"]]) mssg(verbose, "- ", file)
92+
}
93+
7194
packages.to.install <- setdiff(packages.detected, c(packages.installed, exclude.packages))
7295

7396
# detach checkpointed pkgs already loaded
@@ -132,3 +155,6 @@ getSnapshotUrl <- function(snapshotDate, url = mranUrl()){
132155

133156

134157
mssg <- function(x, ...) if(x) message(...)
158+
159+
correctR <- function(x) compareVersion(as.character(utils::packageVersion("base")), x) == 0
160+

R/scanRepoPackages.R

Lines changed: 103 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,78 +2,146 @@
22
projectScanPackages <- function(project = getwd(), verbose = TRUE, use.knitr = FALSE){
33
# detect all package dependencies for a project
44
dir <- normalizePath(project, winslash='/', mustWork=FALSE)
5-
pattern <- if(!use.knitr) "\\.[rR]$" else
6-
"\\.[rR]$|\\.[rR]md$|\\.[rR]nw$|\\.[rR]pres$"
5+
pattern <- if(!use.knitr) "\\.[rR]$|\\.[rR]nw$" else
6+
"\\.[rR]$|\\.[rR]nw$|\\.[rR]md$|\\.[rR]pres$"
77

8-
R_files <- list.files(dir, pattern = pattern, ignore.case = TRUE, recursive = TRUE)
8+
ext_r <- c("R", "Rnw")
9+
ext_k <- c("Rmd", "Rpres", "Rhmtl") # knitr / rmarkdown extensions
910

10-
# ## ignore anything in the checkpoint directory
11-
# R_files <- grep("^checkpoint", R_files, invert = TRUE, value = TRUE)
11+
makePtn <- function(x)sprintf("\\.(%s)$", paste(c(x, tolower(x)), collapse="|"))
1212

13-
pkgs <- unlist(unique(sapply(R_files, deps_by_ext, dir=dir)))
14-
as.vector(pkgs)
13+
files_r <- list.files(dir, pattern = makePtn(ext_r), ignore.case = TRUE, recursive = TRUE)
14+
files_k <- list.files(dir, pattern = makePtn(ext_k), ignore.case = TRUE, recursive = TRUE)
1515

16+
R_files <- files_r
17+
18+
if(length(files_k) > 0) {
19+
if(use.knitr) {
20+
if(!require("knitr")) {
21+
warning("The knitr package is not available and Rmarkdown files will not be parsed")
22+
} else {
23+
R_files <- c(files_r, files_k)
24+
}
25+
} else {
26+
warning("rmarkdown files found and will not be parsed. Set use.knitr = TRUE")
27+
}
28+
}
29+
30+
if(length(R_files) == 0){
31+
list(pkgs = character(), error = character())
32+
} else {
33+
if(interactive()){
34+
z <- lapplyProgressBar(R_files, deps_by_ext, dir=dir, verbose=verbose)
35+
} else {
36+
z <- lapply(R_files, deps_by_ext, dir=dir, verbose=verbose)
37+
}
38+
39+
pkgs <- sort(unique(do.call(c, lapply(z, "[[", "pkgs"))))
40+
error <- sort(unique(do.call(c, lapply(z, "[[", "error"))))
41+
error <- gsub(sprintf("%s[//|\\]*", dir), "", error)
42+
list(pkgs = pkgs, error = error)
43+
}
44+
45+
}
46+
47+
lapplyProgressBar <- function(X, FUN, ...){
48+
env <- environment()
49+
N <- length(X)
50+
counter <- 0
51+
pb <- txtProgressBar(min = 0, max = N, style = 3)
52+
on.exit(close(pb))
53+
54+
wrapper <- function(...){
55+
curVal <- get("counter", envir = env)
56+
assign("counter", curVal + 1, envir = env)
57+
setTxtProgressBar(get("pb", envir = env), curVal + 1)
58+
FUN(...)
59+
}
60+
lapply(X, wrapper, ...)
1661
}
1762

63+
getFileExtension <- function(filename)tolower(gsub(".*\\.", "", filename))
64+
1865

1966

2067
# ad-hoc dispatch based on the file extension
21-
deps_by_ext <- function(file, dir) {
68+
deps_by_ext <- function(file, dir, verbose = TRUE) {
2269
file <- file.path(dir, file)
23-
fileext <- tolower(gsub(".*\\.", "", file))
70+
fileext <- getFileExtension(file)
2471
switch(fileext,
25-
r = deps.R(file),
26-
rmd = deps.Rmd(file),
27-
rnw = deps.Rnw(file),
28-
rpres = deps.Rpres(file),
29-
txt = deps.txt(file),
72+
r = deps.R(file, verbose = verbose),
73+
rmd = deps.Rmd(file, verbose = verbose),
74+
rnw = deps.Rnw(file, verbose = verbose),
75+
rpres = deps.Rpres(file, verbose = verbose),
76+
txt = deps.txt(file, verbose = verbose),
3077
stop("Unrecognized file type '", file, "'")
3178
)
3279
}
3380

3481
deps.Rmd <- deps.Rpres <- function(file, verbose=TRUE) {
35-
tempfile <- tempfile()
82+
tempfile <- tempfile(fileext = ".Rmd")
3683
on.exit(unlink(tempfile))
3784
stopifnot(require("knitr"))
38-
tryCatch(knitr::knit(file, output = tempfile, tangle = TRUE, quiet = TRUE), error = function(e) {
39-
mssg(verbose, "Unable to knit file '", file, "'; cannot parse dependencies")
40-
character()
41-
})
42-
deps.R(tempfile)
85+
p <- tryCatch(
86+
suppressWarnings(suppressMessages(
87+
knitr::knit(file, output = tempfile, tangle = TRUE, quiet = TRUE)
88+
)),
89+
error = function(e) e
90+
)
91+
92+
if(inherits(p, "error")) {
93+
return(list(pkgs=character(), error=file))
94+
}
95+
96+
p <- deps.R(tempfile)
97+
if(length(p[["error"]]) != 0 ) {
98+
p[["error"]] <- file
99+
}
100+
p
43101
}
44102

45103
deps.Rnw <- function(file, verbose=TRUE) {
46-
tempfile <- tempfile()
104+
tempfile <- tempfile(fileext = ".Rnw")
47105
on.exit(unlink(tempfile))
48-
tryCatch(Stangle(file, output = tempfile, quiet = TRUE), error = function(e) {
49-
mssg(verbose, "Unable to stangle file '", file, "'; cannot parse dependencies")
50-
character()
51-
})
52-
deps.R(tempfile)
106+
p <- tryCatch(
107+
suppressWarnings(suppressMessages(
108+
Stangle(file, output = tempfile, quiet = TRUE)
109+
)),
110+
error = function(e) e
111+
)
112+
if(inherits(p, "error")) {
113+
return(list(pkgs=character(), error=file))
114+
}
115+
116+
p <- deps.R(tempfile)
117+
if(length(p[["error"]]) != 0 ) {
118+
p[["error"]] <- file
119+
}
120+
p
53121
}
54122

55123
deps.R <- deps.txt <- function(file, verbose=TRUE) {
56124

57125
if (!file.exists(file)) {
58126
warning("No file at path '", file, "'.")
59-
return(character())
127+
return(list(pkgs=character(), error=file))
60128
}
61129

62130
# build a list of package dependencies to return
63131
pkgs <- character()
64132

65133
# parse file and examine expressions
66-
tryCatch({
134+
p <- tryCatch({
67135
exprs <- suppressWarnings(parse(file, n = -1L))
68136
for (i in seq_along(exprs))
69137
pkgs <- append(pkgs, expressionDependencies(exprs[[i]]))
70-
}, error = function(e) {
71-
warning(paste("Failed to parse", file, "; dependencies in this file will",
72-
"not be discovered."))
73-
})
74-
75-
# return packages
76-
unique(pkgs)
138+
}, error = function(e) e
139+
)
140+
if(inherits(p, "error")) {
141+
list(pkgs=character(), error=file)
142+
} else {
143+
list(pkgs=unique(pkgs), error=character())
144+
}
77145
}
78146

79147
expressionDependencies <- function(e) {

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ To install `checkpoint` directly from github, use the `devtools` package. In yo
9898

9999
```
100100
install.packages("devtools")
101-
devtools::install_github("RevolutionAnalytics/checkpoint", ref="v0.3.4")
101+
devtools::install_github("RevolutionAnalytics/checkpoint")
102102
library("checkpoint")
103103
```
104104

man/checkpoint-package.Rd

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
% Generated by roxygen2 (4.0.2): do not edit by hand
1+
% Generated by roxygen2 (4.1.0): do not edit by hand
2+
% Please edit documentation in R/checkpoint-package.R
23
\docType{package}
34
\name{checkpoint-package}
45
\alias{checkpoint-package}

man/checkpoint.Rd

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1-
% Generated by roxygen2 (4.0.2): do not edit by hand
1+
% Generated by roxygen2 (4.1.0): do not edit by hand
2+
% Please edit documentation in R/checkpoint.R
23
\name{checkpoint}
34
\alias{checkpoint}
45
\title{Configures R session to use packages as they existed on CRAN at time of snapshot.}
56
\usage{
6-
checkpoint(snapshotDate, project = getwd(), verbose = TRUE,
7+
checkpoint(snapshotDate, project = getwd(), R.version, verbose = TRUE,
78
use.knitr = system.file(package = "knitr") != "")
89
}
910
\arguments{
1011
\item{snapshotDate}{Date of snapshot to use in \code{YYYY-MM-DD} format,e.g. \code{"2014-09-17"}. Specify a date on or after \code{"2014-09-17"}. MRAN takes one snapshot per day.}
1112

1213
\item{project}{A project path. This is the path to the root of the project that references the packages to be installed from the MRAN snapshot for the date specified for \code{snapshotDate}. Defaults to current working directory using \code{\link{getwd}()}.}
1314

15+
\item{R.version}{Optional character string, e.g. "3.1.2". If specified, compares the current R.version to the specified R.version, and warns if these are different. This argument allows the original script author to specify a specific version of R to obtain the desired results.}
16+
1417
\item{verbose}{If TRUE, displays progress messages.}
1518

1619
\item{use.knitr}{If TRUE, uses parses all \code{Rmarkdown} files using the \code{knitr} package.}

tests/testthat/test-1-checkpoint.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ packages.to.test.base = c("MASS", "plyr", "XML", "httr","checkpoint", "stats", "
1111
packages.to.test.knitr = c("foreach")
1212
packages.to.test = if(require("knitr")) c(packages.to.test.base, packages.to.test.knitr) else packages.to.test.base
1313

14-
for(snap_date in as.character(c(MRAN.default, MRAN.dates[sample(length(MRAN.dates), 10, replace = FALSE)]))) {
14+
for(snap_date in as.character(c(MRAN.default, MRAN.dates[sample(length(MRAN.dates), 2, replace = FALSE)]))) {
1515
project_root <- file.path(tempfile(), "checkpointtemp")
1616
dir.create(project_root, recursive = TRUE)
1717

0 commit comments

Comments
 (0)