Sitelet https://github.com/RevolutionAnalytics/checkpoint/pull/246/files
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ Description: The goal of checkpoint is to solve the problem of package
server (<https://mran.microsoft.com/>). Immediately after completion
of the rsync mirror process, the process takes a snapshot, thus creating the
archive. Snapshot archives exist starting from 2014-09-17.
Version: 0.4.0
Date: 2017-04-10
Version: 0.4.1
Date: 2017-06-26
Author: Microsoft Corporation
Maintainer: Andrie de Vries <adevries@microsoft.com>
Copyright: Microsoft
Expand All @@ -31,7 +31,8 @@ Suggests:
knitr,
rmarkdown,
testthat(>= 0.9),
MASS
MASS,
darts
VignetteBuilder: knitr
RoxygenNote: 6.0.1
Roxygen: list(markdown = TRUE)
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export(checkpointRemove)
export(getAccessDate)
export(getValidSnapshots)
export(mranUrl)
export(scanForPackages)
export(setSnapshot)
export(unCheckpoint)
importFrom(utils,Stangle)
Expand Down
11 changes: 6 additions & 5 deletions R/checkpoint.R
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@ checkpoint <- function(snapshotDate, project = getwd(),
}
}

authorizeFileSystemUse(checkpointLocation)

fixRstudioBug()


# Create checkpoint folders
authorizeFileSystemUse(checkpointLocation)
if(!createFolders(snapshotDate = snapshotDate,
checkpointLocation = checkpointLocation))
stop("Unable to create checkpoint folders at checkpointLocation = \"",
Expand Down Expand Up @@ -152,9 +152,10 @@ checkpoint <- function(snapshotDate, project = getwd(),
if(isTRUE(scanForPackages)){
mssg(verbose, "Scanning for packages used in this project")
pkgs <- scanForPackages(project, use.knitr = use.knitr,
scan.rnw.with.knitr = scan.rnw.with.knitr,
auto.install.knitr = auto.install.knitr
)
scan.rnw.with.knitr = scan.rnw.with.knitr,
auto.install.knitr = auto.install.knitr,
verbose = verbose
)
packages.detected <- pkgs[["pkgs"]]
mssg(verbose, "- Discovered ", length(packages.detected), " packages")

Expand Down
4 changes: 3 additions & 1 deletion R/checkpoint_internals.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
setMranMirror <- function(
snapshotDate,
snapshotUrl = checkpoint:::getSnapshoturl(/sitelet?url=https%3A%2F%2Fgithub.com%2FRevolutionAnalytics%2Fcheckpoint%2Fpull%2F246%2FsnapshotDate)){
options(repos = snapshotUrl)}
options(repos = snapshotUrl)
}


setLibPaths <- function(checkpointLocation, libPath){
newLoc <- c(libPath,
Expand Down
2 changes: 1 addition & 1 deletion R/checkpoint_log.R
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,4 @@ checkpoint_log <- function(log, snapshotDate, pkg, file = NULL){
)
}
}
}
}
3 changes: 2 additions & 1 deletion R/checkpoint_paths.R
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ file.path <- function(...){

# If the folder doesn't exists, ask user permission to create it
# The argument interactive is purely for testing purposes
authorizeFileSystemUse <- function(checkpointLocation, interactive = interactive()) {
authorizeFileSystemUse <- function(checkpointLocation = "~/",
interactive = base::interactive()) {
checkpointRoot = file.path(checkpointLocation, ".checkpoint")
if(file.exists(checkpointRoot)) {
if(!file.info(checkpointRoot)$isdir)
Expand Down
14 changes: 11 additions & 3 deletions R/scanRepoPackages.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,18 @@ projectScanPackages <- function(...){
scanForPackages(...)
}

#' Scans a project (or folder) for references to packages.
#'
#' @inheritParams checkpoint
#' @return A list with two elements:
#' * pkgs: a character vector with the names of identified packages
#' * error: a character vector with information about files that could not be parsed
#' @export
scanForPackages <- function(project = getwd(), verbose = TRUE,
use.knitr = FALSE,
auto.install.knitr = FALSE,
scan.rnw.with.knitr = FALSE){
use.knitr = FALSE,
auto.install.knitr = FALSE,
scan.rnw.with.knitr = FALSE
){
# detect all package dependencies for a project
dir <- normalizePath(project, winslash='/', mustWork=FALSE)
pattern <- if(!use.knitr) "\\.[rR]$|\\.[rR]nw$" else
Expand Down
30 changes: 30 additions & 0 deletions man/scanForPackages.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion tests/testthat/test-3-checkpoint.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ test.start <- switch(current.R,
"3.1" = "2014-10-01",
"3.2" = "2015-05-01",
"3.3" = "2016-04-01",
"2016-04-01"
"3.4" = "2017-04-24",
"2017-04-24"
)

MRAN.default = test.start[1] # ensure only a single value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,42 @@ vignette: >

Sometimes you want to use create a report using `markdown`, and you want to `checkpoint` the code in this document.

However, running this as part of a `RMarkdown` process is problematic, since the knitting process runs inside a temporary folder that is different from the current working directory.
However, running this as part of a `R Markdown` process is problematic, since the knitting process runs inside a temporary folder that is different from the current working directory.

To resolve this, I propose a hacky solution: create a "manifest" file in the same folder that contains all of the `library()` calls.

# Example

Imagine you have a small script that you want to put in an Rmarkdown document with a checkpoint.
Imagine you have a small script that you want to put in an R Markdown document with a checkpoint.

```r
# demo script
library(MASS)
hist(islands)
# Example from ?darts
library(darts)
x = c(12,16,19,3,17,1,25,19,17,50,18,1,3,17,2,2,13,18,16,2,25,5,5,
1,5,4,17,25,25,50,3,7,17,17,3,3,3,7,11,10,25,1,19,15,4,1,5,12,17,16,
50,20,20,20,25,50,2,17,3,20,20,20,5,1,18,15,2,3,25,12,9,3,3,19,16,20,
5,5,1,4,15,16,5,20,16,2,25,6,12,25,11,25,7,2,5,19,17,17,2,12)
mod = simpleEM(x, niter=100)
e = simpleExpScores(mod$s.final)
oldpar <- par(mfrow=c(1, 2))
drawHeatmap(e)
drawBoard(new=TRUE)
drawAimSpot(e, cex = 5)
par(oldpar)
```

# The checkpoint solution

The only way I've found to get `checkpoint()` to work inside an RMardown document, is really a bit of a hack. The workaround is to create a manifest of required packages, and write this to an R file in the working directory.
The only way I've found to get `checkpoint()` to work inside an R Markdown document, is really a bit of a hack. The workaround is to create a manifest of required packages, and write this to an R file in the working directory.

For example, imagine your R script uses the `MASS` package, then create a manifest file like this:
For example, imagine your R script uses the `darts` package, then create a manifest file like this:

```{r, echo=FALSE, comment=""}
cat("```{r, include=FALSE}", '
# write a manifest to local folder
cat("
library(MASS)
library(darts)
",
file = "manifest.R")
', "```", sep = "")
Expand All @@ -55,10 +66,12 @@ Once this is done, the checkpoint process from here is straight-forward


```{r, echo=FALSE, comment=""}
oldLibPaths <- .libPaths()

cat("```{r, include=FALSE}", '
# Create .checkpoint folder (in tempdir for this example)
td <- tempdir()
dir.create(file.path(td, ".checkpoint"), recursive = TRUE)
dir.create(file.path(td, ".checkpoint"), recursive = TRUE, showWarnings = FALSE)

# Create the checkpoint
library(checkpoint)
Expand All @@ -73,12 +86,13 @@ Now you are ready to put these instructions in an actual code block to see what
```{r checkpoint, warning=FALSE}
# write a manifest to local folder
cat('
library(MASS)
library(darts)
',
file = "manifest.R")

# Create .checkpoint folder (in tempdir for this example)
dir.create(file.path(tempdir(), ".checkpoint"), recursive = TRUE)
dir.create(file.path(tempdir(), ".checkpoint"), recursive = TRUE, showWarnings = FALSE)
options(install.packages.compile.from.source = "no")

# Create the checkpoint
library(checkpoint)
Expand All @@ -87,7 +101,7 @@ checkpoint("2017-03-28", checkpointLocation = tempdir())
```


If this worked, you should see that the library path now points to `tempdir()` and that MASS should be one of only a few package installed:
If this worked, you should see that the library path now points to `tempdir()` and that `darts` is one of only a few package installed:

```{r, eval=FALSE}
.libPaths()
Expand All @@ -103,21 +117,33 @@ installed.packages()[, "Package"]

Now your real R code follows, and it creates the plot, as expected:

```{r, warning=FALSE}
library(MASS)
hist(islands)
```{r, warning=FALSE, fig.asp=4/3}
# Example from ?darts
library(darts)
x = c(12,16,19,3,17,1,25,19,17,50,18,1,3,17,2,2,13,18,16,2,25,5,5,
1,5,4,17,25,25,50,3,7,17,17,3,3,3,7,11,10,25,1,19,15,4,1,5,12,17,16,
50,20,20,20,25,50,2,17,3,20,20,20,5,1,18,15,2,3,25,12,9,3,3,19,16,20,
5,5,1,4,15,16,5,20,16,2,25,6,12,25,11,25,7,2,5,19,17,17,2,12)
mod = simpleEM(x, niter=100)
e = simpleExpScores(mod$s.final)
oldpar <- par(mfrow=c(1, 2))
drawHeatmap(e)
drawBoard(new=TRUE)
drawAimSpot(e, cex = 5)
par(oldpar)
```

# Conclusion

This is a bit of a hack, but points in a direction for getting your RMarkdown script to be checkpointed.
This is a bit of a hack, but points in a direction for getting your R Markdown script to be checkpointed.


```{r, include=FALSE}
```{r, include=TRUE}
# clean up

detach("package:MASS", unload = TRUE)
detach("package:darts", unload = TRUE)
unlink("manifest.R")
unlink(file.path(tempdir(), ".checkpoint"), recursive = TRUE)
unCheckpoint()
unCheckpoint(oldLibPaths)
.libPaths()
```
45 changes: 34 additions & 11 deletions vignettes/checkpoint.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,19 @@ For example, your script may look like this:
library(checkpoint)
checkpoint("2015-04-26", checkpointLocation = tempdir())

library(MASS)
hist(islands)
truehist(islands)
# Example from ?darts
library(darts)
x = c(12,16,19,3,17,1,25,19,17,50,18,1,3,17,2,2,13,18,16,2,25,5,5,
1,5,4,17,25,25,50,3,7,17,17,3,3,3,7,11,10,25,1,19,15,4,1,5,12,17,16,
50,20,20,20,25,50,2,17,3,20,20,20,5,1,18,15,2,3,25,12,9,3,3,19,16,20,
5,5,1,4,15,16,5,20,16,2,25,6,12,25,11,25,7,2,5,19,17,17,2,12)
mod = simpleEM(x, niter=100)
e = simpleExpScores(mod$s.final)
oldpar <- par(mfrow=c(1, 2))
drawHeatmap(e)
drawBoard(new=TRUE)
drawAimSpot(e, cex = 5)
par(oldpar)
```


Expand All @@ -107,10 +117,11 @@ truehist(islands)
Next you want to run the script. Here is what `checkpoint` does:


```{r setup, include=FALSE}
```{r setup, include=FALSE, fig.asp=4/3}

## Create temporary project and set working directory


example_project <- tempdir()

dir.create(example_project, recursive = TRUE, showWarnings = FALSE)
Expand All @@ -124,9 +135,19 @@ example_code <- '
library(checkpoint)
checkpoint("2015-04-26", checkpointLocation = tempdir())

library(MASS)
hist(islands)
truehist(islands)
# Example from ?darts
library(darts)
x = c(12,16,19,3,17,1,25,19,17,50,18,1,3,17,2,2,13,18,16,2,25,5,5,
1,5,4,17,25,25,50,3,7,17,17,3,3,3,7,11,10,25,1,19,15,4,1,5,12,17,16,
50,20,20,20,25,50,2,17,3,20,20,20,5,1,18,15,2,3,25,12,9,3,3,19,16,20,
5,5,1,4,15,16,5,20,16,2,25,6,12,25,11,25,7,2,5,19,17,17,2,12)
mod = simpleEM(x, niter=100)
e = simpleExpScores(mod$s.final)
oldpar <- par(mfrow=c(1, 2))
drawHeatmap(e)
drawBoard(new=TRUE)
drawAimSpot(e, cex = 5)
par(oldpar)
'

cat(example_code, file = file.path(example_project, "checkpoint_example_code.R"))
Expand All @@ -137,12 +158,13 @@ cat(example_code, file = file.path(example_project, "checkpoint_example_code.R")
## Create a folder to contain the checkpoint
## This is optional - the default is to use ~/.checkpoint

dir.create(file.path(tempdir(), ".checkpoint"), recursive = TRUE)
dir.create(file.path(tempdir(), ".checkpoint"), recursive = TRUE, showWarnings = FALSE)

## Create a checkpoint by specifying a snapshot date

library(checkpoint)
checkpoint("2017-04-01", project = example_project, checkpointLocation = tempdir())
checkpoint("2017-04-01", project = example_project,
checkpointLocation = tempdir())
```

### Inspecting the results
Expand All @@ -168,12 +190,13 @@ installed.packages(.libPaths()[1])[, "Package"]
```


```{r cleanup, include=FALSE}
```{r cleanup, include=TRUE}
## cleanup

unlink(example_project, recursive = TRUE)
unlink(file.path(tempdir(), "checkpoint_example_code.R"))
unlink(file.path(tempdir(), ".checkpoint"), recursive = TRUE)
options(repos = oldRepos)
unCheckpoint()
unCheckpoint(oldLibPaths)
.libPaths()
```
Loading