From 4d76f1e6873e3366c7f7442820982a48447f250c Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 23 Aug 2017 14:03:34 -0400 Subject: [PATCH 01/55] logical default for parse since it functions as a flag --- R/simpleCache.R | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/R/simpleCache.R b/R/simpleCache.R index 93f5909..04e842a 100755 --- a/R/simpleCache.R +++ b/R/simpleCache.R @@ -90,7 +90,7 @@ simpleCache = function(cacheName, instruction=NULL, buildEnvir=NULL, cacheDir=getOption("RCACHE.DIR"), cacheSubDir=NULL, timer=FALSE, buildDir=getOption("RBUILD.DIR"), assignToVariable=NULL, loadEnvir=parent.frame(), searchEnvir=getOption("SIMPLECACHE.ENV"), - parse=NULL, nofail=FALSE, batchRegistry=NULL, + parse=FALSE, nofail=FALSE, batchRegistry=NULL, batchResources=NULL, pepSettings=NULL, ignoreLock=FALSE) { # Because R evaluates arguments lazily (only when they are used), @@ -98,14 +98,11 @@ simpleCache = function(cacheName, instruction=NULL, buildEnvir=NULL, # primitive substitute call. Then I can evaluate conditionally # (if the cache needs to be recreated) instruction = substitute(instruction) - if (is.null(parse)) { - if ("character" %in% class(instruction)) { - + if ("character" %in% class(instruction)) { + warning(strwrap("Character instruction; consider wrapping in braces.")) + if (!parse) { + warning("Toggling parse flag to TRUE for character instruction") parse = TRUE - warning(strwrap("Detected a character instruction; consider wrapping - in {} instead of quotes.")) - } else { - parse = FALSE } } if (!is.null(cacheSubDir)) { From 7d95f4cae20dfd7b717e36e4dd4422dce5805e6b Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 23 Aug 2017 16:49:30 -0400 Subject: [PATCH 02/55] update docs to reflect tweaked signature --- man/simpleCache.Rd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/simpleCache.Rd b/man/simpleCache.Rd index b85688b..7c10626 100644 --- a/man/simpleCache.Rd +++ b/man/simpleCache.Rd @@ -13,7 +13,7 @@ simpleCache(cacheName, instruction = NULL, buildEnvir = NULL, cacheDir = getOption("RCACHE.DIR"), cacheSubDir = NULL, timer = FALSE, buildDir = getOption("RBUILD.DIR"), assignToVariable = NULL, loadEnvir = parent.frame(), searchEnvir = getOption("SIMPLECACHE.ENV"), - parse = NULL, nofail = FALSE, batchRegistry = NULL, + parse = FALSE, nofail = FALSE, batchRegistry = NULL, batchResources = NULL, pepSettings = NULL, ignoreLock = FALSE) } \arguments{ From 1427ae031d453925d182c49583da9917363f720d Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 23 Aug 2017 18:24:23 -0400 Subject: [PATCH 03/55] parse instruction iff it's text --- R/simpleCache.R | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/R/simpleCache.R b/R/simpleCache.R index 04e842a..e78eef9 100755 --- a/R/simpleCache.R +++ b/R/simpleCache.R @@ -64,10 +64,6 @@ NULL #' @param buildDir Location of Build files (files with instructions for use If #' the instructions argument is not provided). Defaults to RBUILD.DIR #' global option. -#' @param parse By default, simpleCache will guess whether you want to parse the -#' instruction, based on whether it is quoted. You can overwrite the guess -#' with this parameter; but this may disappear in the future. In general, -#' you should note quote, but use {} around your instructions. #' @param nofail By default, simpleCache throws an error if the instructions #' fail. Use this option to convert this error into a warning. No cache will #' be created, but simpleCache will not then hard-stop your processing. This @@ -90,8 +86,12 @@ simpleCache = function(cacheName, instruction=NULL, buildEnvir=NULL, cacheDir=getOption("RCACHE.DIR"), cacheSubDir=NULL, timer=FALSE, buildDir=getOption("RBUILD.DIR"), assignToVariable=NULL, loadEnvir=parent.frame(), searchEnvir=getOption("SIMPLECACHE.ENV"), - parse=FALSE, nofail=FALSE, batchRegistry=NULL, - batchResources=NULL, pepSettings=NULL, ignoreLock=FALSE) { + nofail=FALSE, batchRegistry=NULL, batchResources=NULL, pepSettings=NULL, + ignoreLock=FALSE) { + + if (!"character" %in% class(cacheName)) { + stop("simpleCache expects the cacheName variable to be a character vector.") + } # Because R evaluates arguments lazily (only when they are used), # it will not evaluate the instruction if I first wrap it in a @@ -99,15 +99,12 @@ simpleCache = function(cacheName, instruction=NULL, buildEnvir=NULL, # (if the cache needs to be recreated) instruction = substitute(instruction) if ("character" %in% class(instruction)) { - warning(strwrap("Character instruction; consider wrapping in braces.")) - if (!parse) { - warning("Toggling parse flag to TRUE for character instruction") - parse = TRUE - } - } - if (!is.null(cacheSubDir)) { - cacheDir = file.path(cacheDir, cacheSubDir) - } + message("Character instruction; consider wrapping in braces.") + parse = TRUE + } else { parse = FALSE } + + # Handle directory paths. + if (!is.null(cacheSubDir)) { cacheDir = file.path(cacheDir, cacheSubDir) } if (is.null(cacheDir)) { message(strwrap("No cacheDir specified. You should set global option RCACHE.DIR with setCacheDir(), or specify a cacheDir parameter directly @@ -115,10 +112,6 @@ simpleCache = function(cacheName, instruction=NULL, buildEnvir=NULL, ", initial="", prefix=" "), tempdir()) cacheDir = tempdir() } - if (!"character" %in% class(cacheName)) { - stop("simpleCache expects the cacheName variable to be a character - vector.") - } if (!file.exists(cacheDir)) { dir.create(cacheDir, recursive=TRUE) From 755cbdca847d1de5b65f8457ebe94e1750ade9ca Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 23 Aug 2017 18:24:57 -0400 Subject: [PATCH 04/55] update docs --- man/simpleCache.Rd | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/man/simpleCache.Rd b/man/simpleCache.Rd index 7c10626..ae85837 100644 --- a/man/simpleCache.Rd +++ b/man/simpleCache.Rd @@ -13,8 +13,8 @@ simpleCache(cacheName, instruction = NULL, buildEnvir = NULL, cacheDir = getOption("RCACHE.DIR"), cacheSubDir = NULL, timer = FALSE, buildDir = getOption("RBUILD.DIR"), assignToVariable = NULL, loadEnvir = parent.frame(), searchEnvir = getOption("SIMPLECACHE.ENV"), - parse = FALSE, nofail = FALSE, batchRegistry = NULL, - batchResources = NULL, pepSettings = NULL, ignoreLock = FALSE) + nofail = FALSE, batchRegistry = NULL, batchResources = NULL, + pepSettings = NULL, ignoreLock = FALSE) } \arguments{ \item{cacheName}{Unique name for the cache. Be careful.} @@ -53,11 +53,6 @@ variable? Defaults to parent.frame.} \item{searchEnvir}{a vector of environments to search for the already loaded cache.} -\item{parse}{By default, simpleCache will guess whether you want to parse the -instruction, based on whether it is quoted. You can overwrite the guess -with this parameter; but this may disappear in the future. In general, -you should note quote, but use {} around your instructions.} - \item{nofail}{By default, simpleCache throws an error if the instructions fail. Use this option to convert this error into a warning. No cache will be created, but simpleCache will not then hard-stop your processing. This From 682d11748dd6df7e3f4a79b41fcb76eeddd55138 Mon Sep 17 00:00:00 2001 From: nsheff Date: Thu, 24 Aug 2017 13:21:40 -0400 Subject: [PATCH 05/55] add 0.3.1 to NEWS. Fix #14 --- NEWS | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index a162b38..649f09c 100644 --- a/NEWS +++ b/NEWS @@ -1,17 +1,25 @@ # Change log All notable changes to this project will be documented in this file. +## [0.3.1] -- 2017-08-21 + + - fixed a bug in unit tests that left behind a test cache in user home dir. + - changes cache building to happen in parent.frame() + - repaired vignette so R code is displayed properly + - added deleteCaches() function and docs + - reduced size of unit test cache for speed increase + ## [0.3.0] -- 2017-08-21 - - Switched default cache dir to tempdir() + - switched default cache dir to tempdir() - changed availCaches() to listCaches() - - changes cache building to happen in parent.frame(), so that any loaded + - changes cache building to happen in globalenv(), so that any loaded packages are available for cache building ## [0.2.1] -- 2017-07-30 - - Added examples + - added examples ## [0.2.0] -- 2017-07-30 @@ -20,4 +28,4 @@ All notable changes to this project will be documented in this file. ## [0.0.1] - - Long-term stable version + - long-term stable version From 5a7ec7e288e5e6ba5bfc9a6bace4f1051289c0fd Mon Sep 17 00:00:00 2001 From: nsheff Date: Thu, 24 Aug 2017 13:22:17 -0400 Subject: [PATCH 06/55] Version to 0.3.2 for github --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 5b535f9..3623dcc 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: simpleCache -Version: 0.3.1 +Version: 0.3.2 Date: 2017-08-21 Title: Simply Caching R Objects Description: Provides intuitive functions for caching R objects, encouraging From f892125b9bf45fde03703a7ec86a0ac4654dc4ae Mon Sep 17 00:00:00 2001 From: nsheff Date: Thu, 24 Aug 2017 13:31:48 -0400 Subject: [PATCH 07/55] update news --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index 649f09c..707e9e0 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,10 @@ # Change log All notable changes to this project will be documented in this file. +## [0.3.2] -- Unreleased + + - remove unnecessary parse argument to simpleCache() + ## [0.3.1] -- 2017-08-21 - fixed a bug in unit tests that left behind a test cache in user home dir. From 90fb876757f1acac6b2db6358dd181c31c68792a Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Tue, 5 Sep 2017 14:33:10 -0400 Subject: [PATCH 08/55] allow user spec of loadEnvir for loadCaches as with simpleCache --- R/loadCaches.R | 6 ++++-- man/loadCaches.Rd | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/R/loadCaches.R b/R/loadCaches.R index b20981e..cef9a77 100644 --- a/R/loadCaches.R +++ b/R/loadCaches.R @@ -4,15 +4,17 @@ #' for stuff you already cached previously, so it won't build any caches. #' #' @param cacheNames Vector of caches to load. +#' @param loadEnvir Environment into which to load each cache. #' @param ... Additional parameters passed to simpleCache. #' @export #' @example #' R/examples/example.R -loadCaches = function(cacheNames, ...) { +loadCaches = function(cacheNames, loadEnvir=NULL, ...) { + if (is.null(loadEnvir)) { loadEnvir = parent.frame(n=2) } for (i in 1:length(cacheNames)) { # By default, load these caches into the environment that # calls loadCaches (which is the grandparent, n=2, of the call to # simpleCache. - simpleCache(cacheNames[i], loadEnvir=parent.frame(n=2), ...) + simpleCache(cacheNames[i], loadEnvir=loadEnvir, ...) } } diff --git a/man/loadCaches.Rd b/man/loadCaches.Rd index b247e1b..e4d8d64 100644 --- a/man/loadCaches.Rd +++ b/man/loadCaches.Rd @@ -4,11 +4,13 @@ \alias{loadCaches} \title{Loads pre-made caches} \usage{ -loadCaches(cacheNames, ...) +loadCaches(cacheNames, loadEnvir = NULL, ...) } \arguments{ \item{cacheNames}{Vector of caches to load.} +\item{loadEnvir}{Environment into which to load each cache.} + \item{...}{Additional parameters passed to simpleCache.} } \description{ From dc8d87f9d71888b44c10ba108cd3c10b2c28f74f Mon Sep 17 00:00:00 2001 From: nsheff Date: Thu, 7 Sep 2017 13:47:37 -0400 Subject: [PATCH 09/55] Cleanup docs for pkgdown --- README.md | 7 +------ _pkgdown.yaml | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 _pkgdown.yaml diff --git a/README.md b/README.md index 53934b4..63281c2 100644 --- a/README.md +++ b/README.md @@ -52,12 +52,7 @@ simpleCache("normSample", { rnorm(1e7, 0,1) }) ``` `simpleCache` also interfaces with the `batchtools` package to let you build -caches on any cluster resource manager. I have produced some [R -vignettes](vignettes/) to get you started. - -* [An introduction to simpleCache](vignettes/simpleCacheIntroduction.Rmd) -* [Sharing caches across projects](vignettes/sharingCaches.Rmd) -* [Generating caches on a cluster](vignettes/clusterCaches.Rmd) +caches on any cluster resource manager. -------------------------------------------------------------------------------- ### simpleCache Philosophy diff --git a/_pkgdown.yaml b/_pkgdown.yaml new file mode 100644 index 0000000..73cef9d --- /dev/null +++ b/_pkgdown.yaml @@ -0,0 +1,22 @@ + +template: + params: + bootswatch: yeti + +navbar: + left: + - text: Vignettes + icon: fa-play-circle + href: articles/index.html + - text: Documentation + icon: fa-pencil + href: reference/index.html + - text: GitHub + icon: fa-github fa-lg + href: https://github.com/databio/simpleCache + + right: + - text: Databio.org + href: http://databio.org + - text: Software & Data + href: http://databio.org/software/ From 2f0a9d79d7fdc54b2061ed50702c7a5fde43d6eb Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Fri, 8 Sep 2017 13:33:26 -0400 Subject: [PATCH 10/55] start on full cache listing --- R/listCaches.R | 60 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/R/listCaches.R b/R/listCaches.R index dff1b03..2c407de 100644 --- a/R/listCaches.R +++ b/R/listCaches.R @@ -8,7 +8,65 @@ #' @export #' @example #' R/examples/example.R -listCaches = function(cacheSubDir="") { +listCaches = function(cacheSubDir="", + full.names=FALSE, suffix=NULL, byFolder=TRUE) { + addFilesIn = function(files, folder) { + contents = list.files(folder) + files[[folder]] = sapply(X=) + } list.files(paste0(getOption("RCACHE.DIR"), cacheSubDir)) + result = listCachesByFolder(cacheSubDir, full.names=full.names) + if (byFolder) result else unlist(result) } + +listCacheFiles = function(folder, full.names=FALSE suffix=NULL) { + if (!file_test("-d", folder) && file_test("-x", folder)) { + warning("Not a searchable directory: ", folder) + return(NULL) + } + pattern = if (is.null(suffix)) NULL else paste0("*", suffix) + sapply(X=list.files(folder, recursive=FALSE, pattern=pattern)) +} + + +# TODO: implement pattern support. +listCachesByFolder = function(cacheSubDir=NULL, full.names=FALSE) { + + listContents = function(folderPath) { + # Handle short-circuit cases (input not a nonempty, searchable folder). + if (!.isSearchableFolder(folderPath)) { return(NULL) } + contents = list.files(folderPath, recursive=FALSE, full.names=full.names) + if (0 == length(contents)) { return(NULL) } + + # Partition into files and folders, collecting the actual files into + # a simple (unnamed) list and applying this function over the list of + # folder names + filesIndexer = sapply(X=contents, FUN=function(item) file_test("-f", item)) + newfiles = contents[filesIndexer] + subfolders = contents[-filesIndexer] + + # Make sure we're applying the function over full paths. + if (!full.names) { + subfolders = sapply(X=subfolders, FUN=function(sf) { file.path(folder, sf) }) + } + + result = list() + result[[folder]] = append(list(newfiles), lapply(X=subfolders, FUN=listContents)) + return(result) + } + + cacheHome = getOption("RCACHE.DIR") + if (is.null(cacheHome) || idential("", cacheHome)) { + if (is.null(cacheSubDir)) { stop("No RCACHE.DIR set and no path to search") } + else { warning(sprintf( + "RCACHE.DIR is null or empty; treating '%s' as search root", cacheSubDir) } + cacheHome = cacheSubDir + } + listContents(cacheHome) +} + + +.isSearchableFolder = function(item) { + file_test("-d", item) && file_test("-x", item) +} From 0d4a384b1d9f27c0f368d3995c60acb79db51ebd Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Fri, 8 Sep 2017 13:34:16 -0400 Subject: [PATCH 11/55] Revert "start on full cache listing" to get back to original dev branch status This reverts commit 2f0a9d79d7fdc54b2061ed50702c7a5fde43d6eb. --- R/listCaches.R | 60 +------------------------------------------------- 1 file changed, 1 insertion(+), 59 deletions(-) diff --git a/R/listCaches.R b/R/listCaches.R index 2c407de..dff1b03 100644 --- a/R/listCaches.R +++ b/R/listCaches.R @@ -8,65 +8,7 @@ #' @export #' @example #' R/examples/example.R -listCaches = function(cacheSubDir="", - full.names=FALSE, suffix=NULL, byFolder=TRUE) { - addFilesIn = function(files, folder) { - contents = list.files(folder) - files[[folder]] = sapply(X=) - } +listCaches = function(cacheSubDir="") { list.files(paste0(getOption("RCACHE.DIR"), cacheSubDir)) - result = listCachesByFolder(cacheSubDir, full.names=full.names) - if (byFolder) result else unlist(result) } - -listCacheFiles = function(folder, full.names=FALSE suffix=NULL) { - if (!file_test("-d", folder) && file_test("-x", folder)) { - warning("Not a searchable directory: ", folder) - return(NULL) - } - pattern = if (is.null(suffix)) NULL else paste0("*", suffix) - sapply(X=list.files(folder, recursive=FALSE, pattern=pattern)) -} - - -# TODO: implement pattern support. -listCachesByFolder = function(cacheSubDir=NULL, full.names=FALSE) { - - listContents = function(folderPath) { - # Handle short-circuit cases (input not a nonempty, searchable folder). - if (!.isSearchableFolder(folderPath)) { return(NULL) } - contents = list.files(folderPath, recursive=FALSE, full.names=full.names) - if (0 == length(contents)) { return(NULL) } - - # Partition into files and folders, collecting the actual files into - # a simple (unnamed) list and applying this function over the list of - # folder names - filesIndexer = sapply(X=contents, FUN=function(item) file_test("-f", item)) - newfiles = contents[filesIndexer] - subfolders = contents[-filesIndexer] - - # Make sure we're applying the function over full paths. - if (!full.names) { - subfolders = sapply(X=subfolders, FUN=function(sf) { file.path(folder, sf) }) - } - - result = list() - result[[folder]] = append(list(newfiles), lapply(X=subfolders, FUN=listContents)) - return(result) - } - - cacheHome = getOption("RCACHE.DIR") - if (is.null(cacheHome) || idential("", cacheHome)) { - if (is.null(cacheSubDir)) { stop("No RCACHE.DIR set and no path to search") } - else { warning(sprintf( - "RCACHE.DIR is null or empty; treating '%s' as search root", cacheSubDir) } - cacheHome = cacheSubDir - } - listContents(cacheHome) -} - - -.isSearchableFolder = function(item) { - file_test("-d", item) && file_test("-x", item) -} From 751ad01289499b36be0b8c32e19205b8e73c1b8c Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 13 Sep 2017 23:35:47 -0400 Subject: [PATCH 12/55] initial implementation of cache staleness check --- R/simpleCache.R | 12 ++++++++++-- R/utility.R | 27 +++++++++++++++++++++++++++ man/simpleCache.Rd | 7 +++++-- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/R/simpleCache.R b/R/simpleCache.R index e78eef9..11cd753 100755 --- a/R/simpleCache.R +++ b/R/simpleCache.R @@ -76,8 +76,10 @@ NULL #' cluster resource managers. Used as the `res` argument to #' batchtools::batchMap() #' @param pepSettings Experimental untested feature. -#' @param ignoreLock internal parameter used for batch job submission; don't +#' @param ignoreLock Internal parameter used for batch job submission; don't #' touch. +#' @param maxStaleness Maximum age of cache, in days, to allow before +#' automatically triggering \code{recreate=TRUE}. #' @export #' @example #' R/examples/example.R @@ -87,7 +89,7 @@ simpleCache = function(cacheName, instruction=NULL, buildEnvir=NULL, buildDir=getOption("RBUILD.DIR"), assignToVariable=NULL, loadEnvir=parent.frame(), searchEnvir=getOption("SIMPLECACHE.ENV"), nofail=FALSE, batchRegistry=NULL, batchResources=NULL, pepSettings=NULL, - ignoreLock=FALSE) { + ignoreLock=FALSE, maxStaleness=NULL) { if (!"character" %in% class(cacheName)) { stop("simpleCache expects the cacheName variable to be a character vector.") @@ -139,6 +141,12 @@ simpleCache = function(cacheName, instruction=NULL, buildEnvir=NULL, ret = NULL # The default, in case the cache construction fails. + if (!recreate && .isStale(cacheFile, maxStaleness)) { + message(sprintf( + "Stale cache: '%s' (age > %d day(s))", cacheFile, maxStaleness)) + recreate = TRUE + } + if(cacheExists & !reload & !recreate) { message("::Object exists (in ", cacheWhere, ")::\t", cacheName) #return(get(cacheName)) diff --git a/R/utility.R b/R/utility.R index 3a7367f..9c03380 100644 --- a/R/utility.R +++ b/R/utility.R @@ -27,6 +27,33 @@ enforceEdgeCharacter = function(string, prependChar="", appendChar="") { return(string) } + +#' Determine if a cache file is sufficiently old to warrant refresh. +#' +#' \code{.isStale} accepts a maximum cache age and checks for an option with +#' that setting under \code{MAX.CACHE.AGE} if such an argument isn't passed. +#' If the indicated file exists and is older than the threshold passed or +#' set as an option, the file is deemed "stale." If an age threshold is +#' provided, no check for an option is performed. If the file does not +#' exist or there's not an age threshold directly passed or set as an option, +#' the result is \code{FALSE}. +#' +#' @param pathCacheFile Path to file to ask about staleness. +#' @param stalenessThreshold Maximum file age before it's "stale." +#' @return \code{TRUE} if the file exists and its age exceeds +#' \code{stalenessThreshold} if given or +#' \code{getOption("MAX.CACHE.AGE")} if no age threshold is passed +#' and that option exists; \code{FALSE} otherwise. +.isStale = function(pathCacheFile, stalenessThreshold=NULL) { + if (!file_test("-f", pathCacheFile)) { return(FALSE) } + if (is.null(stalenessThreshold)) { stalenessThreshold = getOption("MAX.CACHE.AGE") } + if (is.null(stalenessThreshold)) { return(FALSE) } + cacheTime = file.info(pathCacheFile)$cacheTime + cacheAge = difftime(Sys.time(), cacheTime, units="days") + as.numeric(cacheAge) > as.numeric(stalenessThreshold) +} + + # MATLAB-style timing functions to start/stop timer. # These functions were based on an idea by some helpful soul on # Stackoverflow that I can no longer recall... diff --git a/man/simpleCache.Rd b/man/simpleCache.Rd index ae85837..8fad957 100644 --- a/man/simpleCache.Rd +++ b/man/simpleCache.Rd @@ -14,7 +14,7 @@ simpleCache(cacheName, instruction = NULL, buildEnvir = NULL, buildDir = getOption("RBUILD.DIR"), assignToVariable = NULL, loadEnvir = parent.frame(), searchEnvir = getOption("SIMPLECACHE.ENV"), nofail = FALSE, batchRegistry = NULL, batchResources = NULL, - pepSettings = NULL, ignoreLock = FALSE) + pepSettings = NULL, ignoreLock = FALSE, maxStaleness = NULL) } \arguments{ \item{cacheName}{Unique name for the cache. Be careful.} @@ -69,8 +69,11 @@ batchtools::batchMap()} \item{pepSettings}{Experimental untested feature.} -\item{ignoreLock}{internal parameter used for batch job submission; don't +\item{ignoreLock}{Internal parameter used for batch job submission; don't touch.} + +\item{maxStaleness}{Maximum age of cache, in days, to allow before +automatically triggering \code{recreate=TRUE}.} } \description{ simpleCache provides a function (simpleCache()) From 7bd58474a0400937fec199d1fd6a860964da2921 Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 13 Sep 2017 23:47:37 -0400 Subject: [PATCH 13/55] proper time attribute --- R/utility.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/utility.R b/R/utility.R index 9c03380..bb44180 100644 --- a/R/utility.R +++ b/R/utility.R @@ -48,7 +48,7 @@ enforceEdgeCharacter = function(string, prependChar="", appendChar="") { if (!file_test("-f", pathCacheFile)) { return(FALSE) } if (is.null(stalenessThreshold)) { stalenessThreshold = getOption("MAX.CACHE.AGE") } if (is.null(stalenessThreshold)) { return(FALSE) } - cacheTime = file.info(pathCacheFile)$cacheTime + cacheTime = file.info(pathCacheFile)$ctime cacheAge = difftime(Sys.time(), cacheTime, units="days") as.numeric(cacheAge) > as.numeric(stalenessThreshold) } From 01f1bc7f95f9aa0ddc9e632a8864b0347f00037e Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Thu, 14 Sep 2017 12:13:13 -0400 Subject: [PATCH 14/55] change names based on @nsheff suggestion; first test working --- R/simpleCache.R | 10 +++---- R/utility.R | 14 +++++----- tests/testthat/helper-lifespan.R | 26 +++++++++++++++++ tests/testthat/test_cache_lifespan.R | 42 ++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 12 deletions(-) create mode 100644 tests/testthat/helper-lifespan.R create mode 100644 tests/testthat/test_cache_lifespan.R diff --git a/R/simpleCache.R b/R/simpleCache.R index 11cd753..b5f0cd0 100755 --- a/R/simpleCache.R +++ b/R/simpleCache.R @@ -78,8 +78,8 @@ NULL #' @param pepSettings Experimental untested feature. #' @param ignoreLock Internal parameter used for batch job submission; don't #' touch. -#' @param maxStaleness Maximum age of cache, in days, to allow before -#' automatically triggering \code{recreate=TRUE}. +#' @param lifespan Maximum age of cache, in days, to allow before +#' automatically triggering \code{recreate=TRUE}. #' @export #' @example #' R/examples/example.R @@ -89,7 +89,7 @@ simpleCache = function(cacheName, instruction=NULL, buildEnvir=NULL, buildDir=getOption("RBUILD.DIR"), assignToVariable=NULL, loadEnvir=parent.frame(), searchEnvir=getOption("SIMPLECACHE.ENV"), nofail=FALSE, batchRegistry=NULL, batchResources=NULL, pepSettings=NULL, - ignoreLock=FALSE, maxStaleness=NULL) { + ignoreLock=FALSE, lifespan=NULL) { if (!"character" %in% class(cacheName)) { stop("simpleCache expects the cacheName variable to be a character vector.") @@ -141,9 +141,9 @@ simpleCache = function(cacheName, instruction=NULL, buildEnvir=NULL, ret = NULL # The default, in case the cache construction fails. - if (!recreate && .isStale(cacheFile, maxStaleness)) { + if (!recreate && .tooOld(cacheFile, lifespan)) { message(sprintf( - "Stale cache: '%s' (age > %d day(s))", cacheFile, maxStaleness)) + "Stale cache: '%s' (age > %d day(s))", cacheFile, lifespan)) recreate = TRUE } diff --git a/R/utility.R b/R/utility.R index bb44180..34ac2a0 100644 --- a/R/utility.R +++ b/R/utility.R @@ -30,7 +30,7 @@ enforceEdgeCharacter = function(string, prependChar="", appendChar="") { #' Determine if a cache file is sufficiently old to warrant refresh. #' -#' \code{.isStale} accepts a maximum cache age and checks for an option with +#' \code{.tooOld} accepts a maximum cache age and checks for an option with #' that setting under \code{MAX.CACHE.AGE} if such an argument isn't passed. #' If the indicated file exists and is older than the threshold passed or #' set as an option, the file is deemed "stale." If an age threshold is @@ -39,18 +39,18 @@ enforceEdgeCharacter = function(string, prependChar="", appendChar="") { #' the result is \code{FALSE}. #' #' @param pathCacheFile Path to file to ask about staleness. -#' @param stalenessThreshold Maximum file age before it's "stale." +#' @param lifespan Maximum file age before it's "stale." #' @return \code{TRUE} if the file exists and its age exceeds -#' \code{stalenessThreshold} if given or +#' \code{lifespan} if given or #' \code{getOption("MAX.CACHE.AGE")} if no age threshold is passed #' and that option exists; \code{FALSE} otherwise. -.isStale = function(pathCacheFile, stalenessThreshold=NULL) { +.tooOld = function(pathCacheFile, lifespan=NULL) { if (!file_test("-f", pathCacheFile)) { return(FALSE) } - if (is.null(stalenessThreshold)) { stalenessThreshold = getOption("MAX.CACHE.AGE") } - if (is.null(stalenessThreshold)) { return(FALSE) } + if (is.null(lifespan)) { lifespan = getOption("MAX.CACHE.AGE") } + if (is.null(lifespan)) { return(FALSE) } cacheTime = file.info(pathCacheFile)$ctime cacheAge = difftime(Sys.time(), cacheTime, units="days") - as.numeric(cacheAge) > as.numeric(stalenessThreshold) + as.numeric(cacheAge) > as.numeric(lifespan) } diff --git a/tests/testthat/helper-lifespan.R b/tests/testthat/helper-lifespan.R new file mode 100644 index 0000000..8560d23 --- /dev/null +++ b/tests/testthat/helper-lifespan.R @@ -0,0 +1,26 @@ +# Ancillary functions for cache lifespan tests. + +buildTestFrame = function() { data.frame(matrix(1:9, nrow=3)) } + +cleanLSTest = function() { + unlink(file.path(tempdir(), "lifespan"), recursive=TRUE) +} + +cleanCacheFolder = function() { + cacheFolder = getOption("RCACHE.DIR") + if (!.inTmpdir(cacheFolder)) { + stop("Cache folder isn't temporary: ", cacheFolder) + } + do.call(what=file.remove, args=list.files(cacheFolder)) +} + +countCacheFiles = function() { length(list.files(getOption("RCACHE.DIR"))) } + +lifespanTestsTmpdir = function() { file.path(tempdir(), "lifespan") } + +setupLSTest = function() { + dir.create(lifespanTestsTmpdir()) + setCacheDir(lifespanTestsTmpdir()) +} + +.inTmpdir = function(path) { substr(path, 1, length(tempdir())) == tempdir() } diff --git a/tests/testthat/test_cache_lifespan.R b/tests/testthat/test_cache_lifespan.R new file mode 100644 index 0000000..839cec3 --- /dev/null +++ b/tests/testthat/test_cache_lifespan.R @@ -0,0 +1,42 @@ +# Tests for enforcing cache lifespan requirement. + +context("lifespan") + +my_test_that = function(description, instruction) { + setupLSTest() + test_that(description, instruction) + cleanLSTest() +} + +# Negative control +my_test_that("Cache file isn't replaced if no lifespan is specified and recreate=FALSE", { + expect_equal(0, countCacheFiles()) + simpleCache("testDF", recreate=FALSE, instruction={ buildTestFrame() }) + fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") + expect_equal(1, countCacheFiles()) + t0 = file.info(fp)$ctime + simpleCache("testDF", recreate=FALSE, instruction={ buildTestFrame() }) + t1 = file.info(fp)$ctime + expect_equal(1, countCacheFiles()) + expect_equal(t0, t1) +}) + +# Another sort of control +my_test_that("Cache file is replaced if no lifespan is specified and recreate=TRUE", { + +}) + +# Specificity +my_test_that("Cache remains unchanged if younger than explicit lifespan", { + +}) + +# Sensitivity +my_test_that("Cache is replaced if older than explicit lifespan, with ", { + +}) + +# Explicit recreate argument trumps cache lifespan to determine recreation. +my_test_that("Cache is replaced if recreate=TRUE even if cache is fresh", { + +}) From 893996c2df1bc2946c33b6f163b1f77be46a1e68 Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Thu, 14 Sep 2017 12:21:06 -0400 Subject: [PATCH 15/55] finish lifespan tests --- tests/testthat/test_cache_lifespan.R | 50 +++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/tests/testthat/test_cache_lifespan.R b/tests/testthat/test_cache_lifespan.R index 839cec3..523e15e 100644 --- a/tests/testthat/test_cache_lifespan.R +++ b/tests/testthat/test_cache_lifespan.R @@ -8,35 +8,69 @@ my_test_that = function(description, instruction) { cleanLSTest() } +mySimpleCache = function(...) { simpleCache(..., noload=TRUE) } + # Negative control my_test_that("Cache file isn't replaced if no lifespan is specified and recreate=FALSE", { expect_equal(0, countCacheFiles()) - simpleCache("testDF", recreate=FALSE, instruction={ buildTestFrame() }) + mySimpleCache("testDF", recreate=FALSE, instruction={ buildTestFrame() }) fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") expect_equal(1, countCacheFiles()) t0 = file.info(fp)$ctime - simpleCache("testDF", recreate=FALSE, instruction={ buildTestFrame() }) - t1 = file.info(fp)$ctime + mySimpleCache("testDF", recreate=FALSE, instruction={ buildTestFrame() }) expect_equal(1, countCacheFiles()) + t1 = file.info(fp)$ctime expect_equal(t0, t1) }) # Another sort of control my_test_that("Cache file is replaced if no lifespan is specified and recreate=TRUE", { - + expect_equal(0, countCacheFiles()) + mySimpleCache("testDF", instruction={ buildTestFrame() }) + fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") + expect_equal(1, countCacheFiles()) + t0 = file.info(fp)$ctime + mySimpleCache("testDF", recreate=TRUE, instruction={ buildTestFrame() }) + expect_equal(1, countCacheFiles()) + t1 = file.info(fp)$ctime + expect_true(t1 > t0) }) # Specificity my_test_that("Cache remains unchanged if younger than explicit lifespan", { - + expect_equal(0, countCacheFiles()) + mySimpleCache("testDF", instruction={ buildTestFrame() }) + fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") + expect_equal(1, countCacheFiles()) + t0 = file.info(fp)$ctime + mySimpleCache("testDF", lifespan=0.5, instruction={ buildTestFrame() }) + expect_equal(1, countCacheFiles()) + t1 = file.info(fp)$ctime + expect_true(t1 == t0) }) # Sensitivity -my_test_that("Cache is replaced if older than explicit lifespan, with ", { - +my_test_that("Cache is replaced if older than explicit lifespan", { + expect_equal(0, countCacheFiles()) + mySimpleCache("testDF", instruction={ buildTestFrame() }) + fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") + expect_equal(1, countCacheFiles()) + t0 = file.info(fp)$ctime + mySimpleCache("testDF", lifespan=0, instruction={ buildTestFrame() }) + expect_equal(1, countCacheFiles()) + t1 = file.info(fp)$ctime + expect_true(t1 > t0) }) # Explicit recreate argument trumps cache lifespan to determine recreation. my_test_that("Cache is replaced if recreate=TRUE even if cache is fresh", { - + expect_equal(0, countCacheFiles()) + mySimpleCache("testDF", instruction={ buildTestFrame() }) + fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") + expect_equal(1, countCacheFiles()) + t0 = file.info(fp)$ctime + mySimpleCache("testDF", recreate=TRUE, lifespan=0, instruction={ buildTestFrame() }) + expect_equal(1, countCacheFiles()) + t1 = file.info(fp)$ctime + expect_true(t1 >= t0) }) From 36a448f703259dcb5070a2d57b7353ad5ca7aa1b Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Thu, 14 Sep 2017 12:36:24 -0400 Subject: [PATCH 16/55] polish tests files --- tests/testthat/helper-lifespan.R | 20 +++++-------- tests/testthat/test_cache_lifespan.R | 44 ++++++++++++++++++---------- 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/tests/testthat/helper-lifespan.R b/tests/testthat/helper-lifespan.R index 8560d23..79a3ce9 100644 --- a/tests/testthat/helper-lifespan.R +++ b/tests/testthat/helper-lifespan.R @@ -1,26 +1,22 @@ # Ancillary functions for cache lifespan tests. +# Build a small data frame to cache. buildTestFrame = function() { data.frame(matrix(1:9, nrow=3)) } -cleanLSTest = function() { - unlink(file.path(tempdir(), "lifespan"), recursive=TRUE) -} - -cleanCacheFolder = function() { - cacheFolder = getOption("RCACHE.DIR") - if (!.inTmpdir(cacheFolder)) { - stop("Cache folder isn't temporary: ", cacheFolder) - } - do.call(what=file.remove, args=list.files(cacheFolder)) -} +# Remove test case's temp cache folder. +cleanLSTest = function() { unlink(lifespanTestsTmpdir(), recursive=TRUE) } -countCacheFiles = function() { length(list.files(getOption("RCACHE.DIR"))) } +# Count the number of items in the cache folder. +countCacheItems = function() { length(list.files(getOption("RCACHE.DIR"))) } +# Generate path to temp folder for test case. lifespanTestsTmpdir = function() { file.path(tempdir(), "lifespan") } +# Establish a temp folder and set the cache home location to it. setupLSTest = function() { dir.create(lifespanTestsTmpdir()) setCacheDir(lifespanTestsTmpdir()) } +# Check that a path is in the temporary folder. .inTmpdir = function(path) { substr(path, 1, length(tempdir())) == tempdir() } diff --git a/tests/testthat/test_cache_lifespan.R b/tests/testthat/test_cache_lifespan.R index 523e15e..b85aa01 100644 --- a/tests/testthat/test_cache_lifespan.R +++ b/tests/testthat/test_cache_lifespan.R @@ -1,76 +1,88 @@ +# test_cache_lifespan.R # Tests for enforcing cache lifespan requirement. +# The pattern/them for each test is something like: +# 1. Ensure the test case has a fresh, clean folder. +# 2. Create a dummy cache. +# 3. Check that only 1 file is in the cache. +# 4. Grab the cache timestamp. +# 5. Make another simpleCache call. +# 6. Again check that there's a single cache file and grab the timestamp. +# 7. Compare timestamps. + context("lifespan") +# Provide clean cache folder (pre-set) for each test case. my_test_that = function(description, instruction) { setupLSTest() test_that(description, instruction) cleanLSTest() } +# Control loading behavior for these tests to focus on lifespan/recreate effects. mySimpleCache = function(...) { simpleCache(..., noload=TRUE) } # Negative control my_test_that("Cache file isn't replaced if no lifespan is specified and recreate=FALSE", { - expect_equal(0, countCacheFiles()) + expect_equal(0, countCacheItems()) mySimpleCache("testDF", recreate=FALSE, instruction={ buildTestFrame() }) + expect_equal(1, countCacheItems()) fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") - expect_equal(1, countCacheFiles()) t0 = file.info(fp)$ctime mySimpleCache("testDF", recreate=FALSE, instruction={ buildTestFrame() }) - expect_equal(1, countCacheFiles()) + expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime expect_equal(t0, t1) }) # Another sort of control my_test_that("Cache file is replaced if no lifespan is specified and recreate=TRUE", { - expect_equal(0, countCacheFiles()) + expect_equal(0, countCacheItems()) mySimpleCache("testDF", instruction={ buildTestFrame() }) + expect_equal(1, countCacheItems()) fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") - expect_equal(1, countCacheFiles()) t0 = file.info(fp)$ctime mySimpleCache("testDF", recreate=TRUE, instruction={ buildTestFrame() }) - expect_equal(1, countCacheFiles()) + expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime expect_true(t1 > t0) }) # Specificity my_test_that("Cache remains unchanged if younger than explicit lifespan", { - expect_equal(0, countCacheFiles()) + expect_equal(0, countCacheItems()) mySimpleCache("testDF", instruction={ buildTestFrame() }) + expect_equal(1, countCacheItems()) fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") - expect_equal(1, countCacheFiles()) t0 = file.info(fp)$ctime mySimpleCache("testDF", lifespan=0.5, instruction={ buildTestFrame() }) - expect_equal(1, countCacheFiles()) + expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime expect_true(t1 == t0) }) # Sensitivity my_test_that("Cache is replaced if older than explicit lifespan", { - expect_equal(0, countCacheFiles()) + expect_equal(0, countCacheItems()) mySimpleCache("testDF", instruction={ buildTestFrame() }) fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") - expect_equal(1, countCacheFiles()) + expect_equal(1, countCacheItems()) t0 = file.info(fp)$ctime mySimpleCache("testDF", lifespan=0, instruction={ buildTestFrame() }) - expect_equal(1, countCacheFiles()) + expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime expect_true(t1 > t0) }) # Explicit recreate argument trumps cache lifespan to determine recreation. my_test_that("Cache is replaced if recreate=TRUE even if cache is fresh", { - expect_equal(0, countCacheFiles()) + expect_equal(0, countCacheItems()) mySimpleCache("testDF", instruction={ buildTestFrame() }) fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") - expect_equal(1, countCacheFiles()) + expect_equal(1, countCacheItems()) t0 = file.info(fp)$ctime mySimpleCache("testDF", recreate=TRUE, lifespan=0, instruction={ buildTestFrame() }) - expect_equal(1, countCacheFiles()) + expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime - expect_true(t1 >= t0) + expect_true(t1 > t0) }) From c5e8309143475b32c9f3eea2e91093239cc21645 Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Thu, 14 Sep 2017 12:41:51 -0400 Subject: [PATCH 17/55] update docs --- man/simpleCache.Rd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/man/simpleCache.Rd b/man/simpleCache.Rd index 8fad957..766249a 100644 --- a/man/simpleCache.Rd +++ b/man/simpleCache.Rd @@ -14,7 +14,7 @@ simpleCache(cacheName, instruction = NULL, buildEnvir = NULL, buildDir = getOption("RBUILD.DIR"), assignToVariable = NULL, loadEnvir = parent.frame(), searchEnvir = getOption("SIMPLECACHE.ENV"), nofail = FALSE, batchRegistry = NULL, batchResources = NULL, - pepSettings = NULL, ignoreLock = FALSE, maxStaleness = NULL) + pepSettings = NULL, ignoreLock = FALSE, lifespan = NULL) } \arguments{ \item{cacheName}{Unique name for the cache. Be careful.} @@ -72,7 +72,7 @@ batchtools::batchMap()} \item{ignoreLock}{Internal parameter used for batch job submission; don't touch.} -\item{maxStaleness}{Maximum age of cache, in days, to allow before +\item{lifespan}{Maximum age of cache, in days, to allow before automatically triggering \code{recreate=TRUE}.} } \description{ From fd6f9bd20531f2ed3f2057da98eb969c87620e4f Mon Sep 17 00:00:00 2001 From: VP Nagraj Date: Thu, 30 Nov 2017 13:16:34 -0500 Subject: [PATCH 18/55] cleaned up references in bib --- paper/paper.bib | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/paper/paper.bib b/paper/paper.bib index 7290bf6..3a3d74b 100644 --- a/paper/paper.bib +++ b/paper/paper.bib @@ -1,10 +1,10 @@ @Manual{R, - title = {R: A Language and Environment for Statistical Computing}, - author = {{R Core Team}}, - organization = {R Foundation for Statistical Computing}, - address = {Vienna, Austria}, - year = {2016}, - url = {https://www.R-project.org/}, + title = {R: A Language and Environment for Statistical Computing}, + author = {{R Core Team}}, + organization = {R Foundation for Statistical Computing}, + address = {Vienna, Austria}, + year = {2016}, + url = {https://www.R-project.org/}, } @Article{batchtools, @@ -20,23 +20,25 @@ @Article{batchtools } @Article{RPIM, - Author="Sheffield, N. C. and Pierron, G. and Klughammer, J. and Datlinger, P. and Schonegger, A. and Schuster, M. and Hadler, J. and Surdez, D. and Guillemot, D. and Lapouble, E. and Freneaux, P. and Champigneulle, J. and Bouvier, R. and Walder, D. and Ambros, I. M. and Hutter, C. and Sorz, E. and Amaral, A. T. and de Alava, E. and Schallmoser, K. and Strunk, D. and Rinner, B. and Liegl-Atzwanger, B. and Huppertz, B. and Leithner, A. and de Pinieux, G. and Terrier, P. and Laurence, V. and Michon, J. and Ladenstein, R. and Holter, W. and Windhager, R. and Dirksen, U. and Ambros, P. F. and Delattre, O. and Kovar, H. and Bock, C. and Tomazou, E. M. ", - Title="{{D}{N}{A} methylation heterogeneity defines a disease spectrum in {E}wing sarcoma}", - Journal="Nat. Med.", - Year="2017", - Volume="23", - Number="3", - Pages="386--395", - Month="Mar" + author="Sheffield, N. C. and Pierron, G. and Klughammer, J. and Datlinger, P. and Schonegger, A. and Schuster, M. and Hadler, J. and Surdez, D. and Guillemot, D. and Lapouble, E. and Freneaux, P. and Champigneulle, J. and Bouvier, R. and Walder, D. and Ambros, I. M. and Hutter, C. and Sorz, E. and Amaral, A. T. and de Alava, E. and Schallmoser, K. and Strunk, D. and Rinner, B. and Liegl-Atzwanger, B. and Huppertz, B. and Leithner, A. and de Pinieux, G. and Terrier, P. and Laurence, V. and Michon, J. and Ladenstein, R. and Holter, W. and Windhager, R. and Dirksen, U. and Ambros, P. F. and Delattre, O. and Kovar, H. and Bock, C. and Tomazou, E. M. ", + title={DNA methylation heterogeneity defines a disease spectrum in Ewing sarcoma}, + journal={Nature Medicine}, + year={2017}, + volume={23}, + number={3}, + pages={386-395}, + month={Mar}, + doi = {10.1038/nm.4273} } @Article{LOLA, - Author="Sheffield, N. C. and Bock, C. ", - Title="{{L}{O}{L}{A}: enrichment analysis for genomic region sets and regulatory elements in {R} and {B}ioconductor}", - Journal="Bioinformatics", - Year="2016", - Volume="32", - Number="4", - Pages="587--589", - Month="Feb" + author={Sheffield, N. C. and Bock, C.}, + title="{LOLA: enrichment analysis for genomic region sets and regulatory elements in R and Bioconductor}, + journal={Bioinformatics}, + year={2016}, + volume={32}, + number={4}, + pages={587-589}, + month={Feb}, + doi = {10.1093/bioinformatics/btv612} } From d702b57e818c7126d94ba04a3654a8e952a214e9 Mon Sep 17 00:00:00 2001 From: VP Nagraj Date: Thu, 30 Nov 2017 13:35:38 -0500 Subject: [PATCH 19/55] changes to contributing documents as per joss suggestions --- .Rbuildignore | 3 ++- .github/CONTRIBUTING.md | 20 ++++++++++++++++++++ .github/issue_template.md | 8 ++++++++ .github/pull_request_template.md | 16 ++++++++++++++++ README.md | 2 ++ 5 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 .github/CONTRIBUTING.md create mode 100644 .github/issue_template.md create mode 100644 .github/pull_request_template.md diff --git a/.Rbuildignore b/.Rbuildignore index ead92e5..af564cd 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -3,4 +3,5 @@ ^\.travis\.yml$ ^cran-comments.md$ ^CONDUCT\.md$ -^paper$ \ No newline at end of file +^paper$ +.github \ No newline at end of file diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..0b5aa2c --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,20 @@ +# CONTRIBUTING # + +### Please contribute! + +We love collaboration. + +### Bugs? + +* Submit an issue on the [Issues page](https://github.com/databio/simpleCache/issues) + +### Code contributions + +* Fork this repo to your Github account +* Clone your version on your account down to your machine from your account, e.g,. `git clone https://github.com/databio/simpleCache.git` +* Make sure to track progress upstream (i.e., on our version of `simpleCache` at `databio/simpleCache`) by doing `git remote add upstream https://github.com/databio/simpleCache.git`. Before making changes make sure to pull changes in from upstream by doing either `git fetch upstream` then merge later or `git pull upstream` to fetch and merge in one step +* Make your changes (bonus points for making changes on a new feature branch) +* Push up to your account +* Submit a pull request to home base (likely master branch, but check to make sure) at `databio/simpleCache` + +### Thanks for contributing! \ No newline at end of file diff --git a/.github/issue_template.md b/.github/issue_template.md new file mode 100644 index 0000000..6387c0d --- /dev/null +++ b/.github/issue_template.md @@ -0,0 +1,8 @@ + + +
Session Info + +```r + +``` +
\ No newline at end of file diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..8d3e248 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,16 @@ + + +## Description + + +## Related Issue + + +## Example + + + \ No newline at end of file diff --git a/README.md b/README.md index 529b67f..e19abc9 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,8 @@ change. `simpleCache` is licensed under the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause). Questions, feature requests and bug reports are welcome via the [issue queue](https://github.com/databio/simpleCache/issues). The maintainer will review pull requests and incorporate contributions at his discretion. +For more information refer to the contributing document and pull request / issue templates in the [.github folder](https://github.com/databio/simpleCache/tree/master/.github) of this repository. + From 7e740fd3e3138ff14f2b8ef1d1bb9efb03fb63d5 Mon Sep 17 00:00:00 2001 From: VP Nagraj Date: Fri, 1 Dec 2017 18:00:37 -0500 Subject: [PATCH 20/55] enforceEdgeCharacter is not used anywhere commenting out for now --- R/utility.R | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/R/utility.R b/R/utility.R index 3a7367f..b1241a4 100644 --- a/R/utility.R +++ b/R/utility.R @@ -10,22 +10,22 @@ # These functions should probably remain interior to the package (not exported) # -enforceEdgeCharacter = function(string, prependChar="", appendChar="") { - if (string=="" | is.null(string)) { - return(string) - } - if(!is.null(appendChar)) { - if (substr(string,nchar(string), nchar(string)) != appendChar) { # +1 ? - string = paste0(string, appendChar); - } - } - if (!is.null(prependChar)) { - if (substr(string,1,1) != prependChar) { # +1 ? - string = paste0(prependChar, string) - } - } - return(string) -} +# enforceEdgeCharacter = function(string, prependChar="", appendChar="") { +# if (string=="" | is.null(string)) { +# return(string) +# } +# if(!is.null(appendChar)) { +# if (substr(string,nchar(string), nchar(string)) != appendChar) { # +1 ? +# string = paste0(string, appendChar); +# } +# } +# if (!is.null(prependChar)) { +# if (substr(string,1,1) != prependChar) { # +1 ? +# string = paste0(prependChar, string) +# } +# } +# return(string) +# } # MATLAB-style timing functions to start/stop timer. # These functions were based on an idea by some helpful soul on From 6014696164cbaad91af034558e222a69e042e7bc Mon Sep 17 00:00:00 2001 From: VP Nagraj Date: Fri, 1 Dec 2017 18:04:02 -0500 Subject: [PATCH 21/55] more tests and organization of test code --- tests/testthat/test_all.R | 76 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/tests/testthat/test_all.R b/tests/testthat/test_all.R index 05976d0..04d2eda 100644 --- a/tests/testthat/test_all.R +++ b/tests/testthat/test_all.R @@ -1,6 +1,25 @@ library(simpleCache) -context("Test_that") +context("error checking") + +test_that("error checking behaves as expected", { + + # message when cacheDir isn't defined + expect_message(simpleCache("normSample", { rnorm(5e3, 0,1) }), regexp = "^No cacheDir specified.") + + # warning when instruction is not expression + expect_warning(simpleCache("normSample", instruction = "rnorm(5e3, 0,1)", cacheDir = tempdir(), recreate=TRUE)) + + # error when instruction and buildDir are null + expect_error(simpleCache("normSample", instruction = NULL, buildDir = NULL, cacheDir = tempdir(), recreate=TRUE)) + + # error when cacheName is not character + expect_error(simpleCache(12345, instruction = { rnorm(5e3, 0,1) }, buildDir = NULL, cacheDir = tempdir(), recreate=TRUE)) + + # we must clean up any temporary caches we make + deleteCaches("normSample", force=TRUE) + +}) test_that("Caching respects files existing", { setCacheDir(tempdir()) @@ -11,7 +30,7 @@ test_that("Caching respects files existing", { simpleCache("normSample", { rnorm(5e3, 0,1) }, recreate=TRUE) expect_equal(signif(normSample[1], 6), -1.51637) - # Should not evaluate: + # Should not evaluate simpleCache("normSample", { rnorm(5e3, 0,1) }) expect_equal(signif(normSample[1], 6), -1.51637) @@ -26,3 +45,56 @@ test_that("Caching respects files existing", { }) +context("basic functionality") + +test_that("timer works", { + + setCacheDir(tempdir()) + timeout <- capture_messages(simpleCache("normSample", { rnorm(5e3, 0,1) }, recreate=TRUE, timer = TRUE))[2] + expect_match(timeout, "<[0-9][0-9]h [0-9][0-9]m [0-9].[0-9]s>") + + # we must clean up any temporary caches we make + deleteCaches("normSample", force=TRUE) + +}) + +test_that("cache can be created without loading", { + + expect_null(simpleCache("normSample", { rnorm(5e3, 0,1) }, recreate = TRUE, noload = TRUE, cacheDir = tempdir())) + + # we must clean up any temporary caches we make + deleteCaches("normSample", force=TRUE) + +}) + +test_that("option setting works", { + + # set all options + setCacheDir(tempdir()) + setSharedCacheDir(tempdir()) + setCacheBuildDir(tempdir()) + + # capture output and check + options_out <- capture_messages(viewCacheDirs()) + + expect_true(grepl(tempdir(), options_out[1])) + expect_true(grepl(tempdir(), options_out[2])) + expect_true(grepl(tempdir(), options_out[3])) + +}) + + +context("misc") + +test_that("listCaches returns name of given cache", { + + setCacheDir(tempdir()) + set.seed(1) + simpleCache("normSample", { rnorm(5e3, 0,1) }, recreate=TRUE) + expect_true("normSample.RData" %in% listCaches()) + + # we must clean up any temporary caches we make + deleteCaches("normSample", force=TRUE) + +}) + From 695e0913ded6fb197fc546abba6219b4b483f009 Mon Sep 17 00:00:00 2001 From: VP Nagraj Date: Mon, 4 Dec 2017 10:08:51 -0500 Subject: [PATCH 22/55] even more tests --- tests/testthat/test_all.R | 76 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/tests/testthat/test_all.R b/tests/testthat/test_all.R index 04d2eda..928c086 100644 --- a/tests/testthat/test_all.R +++ b/tests/testthat/test_all.R @@ -2,11 +2,25 @@ library(simpleCache) context("error checking") -test_that("error checking behaves as expected", { +test_that("notifications and messages as expected", { + + # message if cache exists + simpleCache("normSample", instruction = {rnorm(5e3, 0,1)}, cacheDir = tempdir(), recreate=TRUE) + expect_message(simpleCache("normSample", instruction = {rnorm(5e3, 0,1)}, cacheDir = tempdir(), recreate=FALSE, noload = TRUE), "^::Cache exists") + deleteCaches("normSample", force = TRUE) + + # storeCache should not accept non-character cacheName + expect_error(storeCache(cacheName = normSample, recreate = TRUE, cacheDir = tempdir()), "storeCache expects the cacheName variable to be a character vector.") # message when cacheDir isn't defined expect_message(simpleCache("normSample", { rnorm(5e3, 0,1) }), regexp = "^No cacheDir specified.") + # error when buildDir is empty without instruction + expect_error(simpleCache("normSample", cacheDir = tempdir(), buildDir = tempdir(), recreate = TRUE), "::Error::\tNo instruction or RBuild file provided.") + + # error when buildEnvir includes "instruction" + expect_error(simpleCache("normSample", { rnorm(5e3, 0,1) }, buildEnvir = list(instruction="foo"), recreate=TRUE, cacheDir = tempdir()), "Can't provide a variable named 'instruction' in buildEnvir") + # warning when instruction is not expression expect_warning(simpleCache("normSample", instruction = "rnorm(5e3, 0,1)", cacheDir = tempdir(), recreate=TRUE)) @@ -16,8 +30,11 @@ test_that("error checking behaves as expected", { # error when cacheName is not character expect_error(simpleCache(12345, instruction = { rnorm(5e3, 0,1) }, buildDir = NULL, cacheDir = tempdir(), recreate=TRUE)) + # message when return is NULL + expect_message(simpleCache("normSample", instruction = {normSample <- NULL}, recreate = TRUE, cacheDir = tempdir()), "NULL value returned, no cache created") + # we must clean up any temporary caches we make - deleteCaches("normSample", force=TRUE) + deleteCaches("normSample", force=TRUE, cacheDir = tempdir()) }) @@ -62,17 +79,35 @@ test_that("cache can be created without loading", { expect_null(simpleCache("normSample", { rnorm(5e3, 0,1) }, recreate = TRUE, noload = TRUE, cacheDir = tempdir())) + expect_true("normSample.RData" %in% listCaches()) + # we must clean up any temporary caches we make deleteCaches("normSample", force=TRUE) }) +test_that("object can be stored as cache", { + + normSample2 <<- rnorm(5e3,0,1) + + expect_message(storeCache("normSample2", cacheDir = NULL, recreate = TRUE), "^You must set global option RCACHE.DIR") + + expect_message(storeCache("normSample2", cacheDir = tempdir(), recreate = TRUE), "^::Creating cache::") + + expect_message(storeCache("normSample2", cacheDir = tempdir(), recreate = FALSE), "^::Cache already exists") + + # we must clean up any temporary caches we make + deleteCaches("normSample2", force=TRUE) + +}) + test_that("option setting works", { # set all options setCacheDir(tempdir()) setSharedCacheDir(tempdir()) setCacheBuildDir(tempdir()) + addCacheSearchEnvironment("cacheEnv") # capture output and check options_out <- capture_messages(viewCacheDirs()) @@ -80,10 +115,47 @@ test_that("option setting works", { expect_true(grepl(tempdir(), options_out[1])) expect_true(grepl(tempdir(), options_out[2])) expect_true(grepl(tempdir(), options_out[3])) + expect_true(grepl("cacheEnv", options_out[4])) + + # reset the cache search option + resetCacheSearchEnvironment() + + # check to make sure it is gone + options_out <- capture_messages(viewCacheDirs()) + expect_true(!grepl("cacheEnv", options_out[4])) }) +test_that("objects pass through in buildEnvir", { + + setCacheDir(tempdir()) + + set.seed(1) + simpleCache("piSample", { pi^x }, buildEnvir = list(x=2), recreate=TRUE, timer = TRUE) + rm(piSample) + + simpleCache("piSample", reload = TRUE) + + expect_equal(signif(piSample, 3), 9.87) + + # we must clean up any temporary caches we make + deleteCaches("piSample", force=TRUE) + +}) +test_that("caches can be loaded", { + + setCacheDir(tempdir()) + + simpleCache("loadSample", { rnorm(5e3, 0,1) }, recreate=TRUE) + loadCaches("loadSample") + + expect_true("loadSample" %in% ls()) + + # we must clean up any temporary caches we make + deleteCaches("loadSample", force=TRUE) + +}) context("misc") test_that("listCaches returns name of given cache", { From bfe1bb4decd3c6c9cb74162fd1b5a22317a0a5bc Mon Sep 17 00:00:00 2001 From: VP Nagraj Date: Mon, 4 Dec 2017 10:40:07 -0500 Subject: [PATCH 23/55] updates to DESCRIPTION as per JOSS suggestions --- DESCRIPTION | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index d385b12..4b14f0e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -13,7 +13,6 @@ Description: Provides intuitive functions for caching R objects, encouraging Authors@R: c(person("VP", "Nagraj", email = "vpnagraj@virginia.edu", role = c("aut")), person("Nathan", "Sheffield", email = "nathan@code.databio.org", role = c("aut", "cre"))) -Maintainer: Nathan Sheffield Suggests: knitr, testthat @@ -21,6 +20,6 @@ Enhances: batchtools VignetteBuilder: knitr License: BSD_2_clause + file LICENSE Encoding: UTF-8 -URL: http://www.github.com/databio/simpleCache -BugReports: http://www.github.com/databio/simpleCache +URL: https://www.github.com/databio/simpleCache +BugReports: https://www.github.com/databio/simpleCache RoxygenNote: 6.0.1.9000 From f3300638a012e506665da7991b8b9c62ed602025 Mon Sep 17 00:00:00 2001 From: VP Nagraj Date: Mon, 4 Dec 2017 11:04:31 -0500 Subject: [PATCH 24/55] documentation now formatted with appropriate links out --- R/simpleCache.R | 38 +++++++++++++++++--------------------- man/simpleCache.Rd | 38 +++++++++++++++++--------------------- 2 files changed, 34 insertions(+), 42 deletions(-) diff --git a/R/simpleCache.R b/R/simpleCache.R index 93f5909..50cae1c 100755 --- a/R/simpleCache.R +++ b/R/simpleCache.R @@ -1,11 +1,8 @@ ## Package documentation #' Provides intuitive functions for caching R objects, encouraging faster #' reproducible and restartable R analysis -#' -#' simpleCache provides a function (simpleCache()) #' -#' @references \url{https://github.com/nsheff/} -## @import if you import any packages; here. +#' @references \url{https://github.com/databio/simpleCache} #' @docType package #' @name simpleCache #' @author Nathan Sheffield @@ -23,10 +20,10 @@ NULL #' troubles if you misuse the caching system. The object should be considered #' static. #' -#' You should pass a bracketed R code snippet like `{ rnorm(500) }` as the +#' You should pass a bracketed R code snippet like \code{rnorm(500)} as the #' instruction, and simpleCache will create the object. Alternatively, if the #' code to create the cache is large, you can put an R script called object.R in -#' the RBUILD.DIR (the name of the file *must* match the name of the object it +#' the \code{\link[=setCacheBuildDir]{RBUILD.DIR}} (the name of the file *must* match the name of the object it #' creates *exactly*). If you don't provide an instruction, the function sources #' RBUILD.DIR/object.R and caches the result as the object. This source file @@ -51,34 +48,33 @@ NULL #' @param noload noload is useful for: you want to create the caches, but not #' load them if they aren't there (like a cache creation loop). #' @param cacheDir The directory where caches are saved (and loaded from). -#' Defaults to the global RCACHE.DIR variable -#' @param cacheSubDir You can specify a subdirectory within the cacheDir -#' variable. Defaults to NULL. -#' @param assignToVariable By default, simpleCache assigns the cache to a -#' variable named cacheName; you can overrule that here. +#' Defaults to the global \code{\link[=setCacheDir]{RCACHE.DIR}} RCACHE.DIR variable +#' @param cacheSubDir You can specify a subdirectory within the \code{cacheDir} +#' variable. Defaults to \code{NULL}. +#' @param assignToVariable By default, \code{simpleCache} assigns the cache to a +#' variable named \code{cacheName}; you can overrule that here. #' @param loadEnvir Into which environment would you like to load the -#' variable? Defaults to parent.frame. +#' variable? Defaults to \code{\link[base]{parent.frame}}. #' @param searchEnvir a vector of environments to search for the already loaded #' cache. #' @param timer Report how long it took to create the cache? #' @param buildDir Location of Build files (files with instructions for use If -#' the instructions argument is not provided). Defaults to RBUILD.DIR -#' global option. -#' @param parse By default, simpleCache will guess whether you want to parse the +#' the instructions argument is not provided). Defaults to \code{\link[=setCacheBuildDir]{RBUILD.DIR}} global option. +#' @param parse By default, \code{simpleCache} will guess whether you want to parse the #' instruction, based on whether it is quoted. You can overwrite the guess #' with this parameter; but this may disappear in the future. In general, -#' you should note quote, but use {} around your instructions. -#' @param nofail By default, simpleCache throws an error if the instructions +#' you should note quote, but use \{ \} around your instructions. +#' @param nofail By default, \code{simpleCache} throws an error if the instructions #' fail. Use this option to convert this error into a warning. No cache will #' be created, but simpleCache will not then hard-stop your processing. This #' is useful, for example, if you are creating a bunch of caches and it's ok #' if some of them do not complete. -#' @param batchRegistry A batchtools registry object (built with -#' batchtools::makeRegistry()). If provided, this cache will be created on +#' @param batchRegistry A \code{batchtools} registry object (built with +#' \code{\link[batchtools]{makeRegistry}}). If provided, this cache will be created on #' the cluster using your batchtools configuration #' @param batchResources A list of variables to provide to batchtools for -#' cluster resource managers. Used as the `res` argument to -#' batchtools::batchMap() +#' cluster resource managers. Used as the \code{res} argument to +#' \code{\link[batchtools]{batchMap}} #' @param pepSettings Experimental untested feature. #' @param ignoreLock internal parameter used for batch job submission; don't #' touch. diff --git a/man/simpleCache.Rd b/man/simpleCache.Rd index b85688b..b1d6b73 100644 --- a/man/simpleCache.Rd +++ b/man/simpleCache.Rd @@ -4,7 +4,6 @@ \name{simpleCache} \alias{simpleCache} \alias{simpleCache-package} -\alias{simpleCache} \title{Provides intuitive functions for caching R objects, encouraging faster reproducible and restartable R analysis} \usage{ @@ -33,44 +32,43 @@ for evaluating the code in instruction.} load them if they aren't there (like a cache creation loop).} \item{cacheDir}{The directory where caches are saved (and loaded from). -Defaults to the global RCACHE.DIR variable} +Defaults to the global \code{\link[=setCacheDir]{RCACHE.DIR}} RCACHE.DIR variable} -\item{cacheSubDir}{You can specify a subdirectory within the cacheDir -variable. Defaults to NULL.} +\item{cacheSubDir}{You can specify a subdirectory within the \code{cacheDir} +variable. Defaults to \code{NULL}.} \item{timer}{Report how long it took to create the cache?} \item{buildDir}{Location of Build files (files with instructions for use If -the instructions argument is not provided). Defaults to RBUILD.DIR -global option.} +the instructions argument is not provided). Defaults to \code{\link[=setCacheBuildDir]{RBUILD.DIR}} global option.} -\item{assignToVariable}{By default, simpleCache assigns the cache to a -variable named cacheName; you can overrule that here.} +\item{assignToVariable}{By default, \code{simpleCache} assigns the cache to a +variable named \code{cacheName}; you can overrule that here.} \item{loadEnvir}{Into which environment would you like to load the -variable? Defaults to parent.frame.} +variable? Defaults to \code{\link[base]{parent.frame}}.} \item{searchEnvir}{a vector of environments to search for the already loaded cache.} -\item{parse}{By default, simpleCache will guess whether you want to parse the +\item{parse}{By default, \code{simpleCache} will guess whether you want to parse the instruction, based on whether it is quoted. You can overwrite the guess with this parameter; but this may disappear in the future. In general, -you should note quote, but use {} around your instructions.} +you should note quote, but use \{ \} around your instructions.} -\item{nofail}{By default, simpleCache throws an error if the instructions +\item{nofail}{By default, \code{simpleCache} throws an error if the instructions fail. Use this option to convert this error into a warning. No cache will be created, but simpleCache will not then hard-stop your processing. This is useful, for example, if you are creating a bunch of caches and it's ok if some of them do not complete.} -\item{batchRegistry}{A batchtools registry object (built with -batchtools::makeRegistry()). If provided, this cache will be created on +\item{batchRegistry}{A \code{batchtools} registry object (built with + \code{\link[batchtools]{makeRegistry}}). If provided, this cache will be created on the cluster using your batchtools configuration} \item{batchResources}{A list of variables to provide to batchtools for -cluster resource managers. Used as the `res` argument to -batchtools::batchMap()} +cluster resource managers. Used as the \code{res} argument to +\code{\link[batchtools]{batchMap}}} \item{pepSettings}{Experimental untested feature.} @@ -78,8 +76,6 @@ batchtools::batchMap()} touch.} } \description{ -simpleCache provides a function (simpleCache()) - Given a unique name for an R object, and instructions for how to make that object, use the simpleCache function to create and cache or load the object. This should be used for computations that take a long time and generate a @@ -89,10 +85,10 @@ troubles if you misuse the caching system. The object should be considered static. } \details{ -You should pass a bracketed R code snippet like `{ rnorm(500) }` as the +You should pass a bracketed R code snippet like \code{rnorm(500)} as the instruction, and simpleCache will create the object. Alternatively, if the code to create the cache is large, you can put an R script called object.R in -the RBUILD.DIR (the name of the file *must* match the name of the object it +the \code{\link[=setCacheBuildDir]{RBUILD.DIR}} (the name of the file *must* match the name of the object it creates *exactly*). If you don't provide an instruction, the function sources RBUILD.DIR/object.R and caches the result as the object. This source file *must* create an object with the same name of the object. If you already have @@ -131,7 +127,7 @@ simpleCache("normSample") loadCaches(c("normSample", "normSample2"), reload=TRUE) } \references{ -\url{https://github.com/nsheff/} +\url{https://github.com/databio/simpleCache} } \author{ Nathan Sheffield From a5643f1c4125b98e7abbf795cd0d4385298c9bb9 Mon Sep 17 00:00:00 2001 From: VP Nagraj Date: Mon, 4 Dec 2017 12:48:38 -0500 Subject: [PATCH 25/55] more updates to formatting and linking man pages --- R/cacheDirectories.R | 6 +++--- R/loadCaches.R | 2 +- R/sharedCaches.R | 6 +++--- R/simpleCache.R | 2 +- R/storeCache.R | 12 ++++++------ man/loadCaches.Rd | 2 +- man/resetCacheSearchEnvironment.Rd | 4 ++-- man/setCacheDir.Rd | 4 ++-- man/setSharedCacheDir.Rd | 2 +- man/simpleCache.Rd | 2 +- man/simpleCacheGlobal.Rd | 2 +- man/simpleCacheShared.Rd | 2 +- man/simpleCacheSharedGlobal.Rd | 2 +- man/storeCache.Rd | 12 ++++++------ 14 files changed, 30 insertions(+), 30 deletions(-) diff --git a/R/cacheDirectories.R b/R/cacheDirectories.R index 9ecaabe..8f3f430 100644 --- a/R/cacheDirectories.R +++ b/R/cacheDirectories.R @@ -6,7 +6,7 @@ # caches. #' Sets a global variable specifying the default cache directory for -#' simpleCache() calls. +#' \code{\link{simpleCache}} calls. #' #' @param cacheDir Directory where caches should be stored #' @export @@ -19,7 +19,7 @@ setCacheDir = function(cacheDir) { #' Set shared cache directory #' #' Sets global variable specifying the default cache directory for -#' simpleCacheShared() calls; this function is simply a helper alias for caching +#' \code{\link{simpleCacheShared}} calls; this function is simply a helper alias for caching #' results that will be used across projects. #' #' @param sharedCacheDir Directory where shared caches should be stored @@ -59,7 +59,7 @@ addCacheSearchEnvironment = function(addEnv) { options(SIMPLECACHE.ENV=append(addEnv, getOption("SIMPLECACHE.ENV"))) } -#' Sets global option of cache search environments to NULL. +#' Sets global option of cache search environments to \code{NULL}. #' #' @export resetCacheSearchEnvironment = function() { diff --git a/R/loadCaches.R b/R/loadCaches.R index b20981e..0368c69 100644 --- a/R/loadCaches.R +++ b/R/loadCaches.R @@ -4,7 +4,7 @@ #' for stuff you already cached previously, so it won't build any caches. #' #' @param cacheNames Vector of caches to load. -#' @param ... Additional parameters passed to simpleCache. +#' @param ... Additional parameters passed to \code{\link{simpleCache}}. #' @export #' @example #' R/examples/example.R diff --git a/R/sharedCaches.R b/R/sharedCaches.R index 4fc0074..3f99a81 100644 --- a/R/sharedCaches.R +++ b/R/sharedCaches.R @@ -8,7 +8,7 @@ #' (instead of the typical default PROJECT directory) #' -#' @param ... Parameters passed to simpleCache(). +#' @param ... Parameters passed to \code{\link{simpleCache}}. #' @export simpleCacheShared = function(...) { # Since this is a function calling this, I have to set the loadEnvir here, @@ -22,7 +22,7 @@ simpleCacheShared = function(...) { #' simpleCache normally loads variables into the calling environment; this #' ensures that the variables are loaded in the global environment. #' -#' @param ... Parameters passed to simpleCache(). +#' @param ... Parameters passed to \code{\link{simpleCache}}. #' @export simpleCacheGlobal = function(...) { simpleCache(..., loadEnvir=globalenv()) @@ -30,7 +30,7 @@ simpleCacheGlobal = function(...) { #' Helper alias for loading shared caches into the global environment. #' -#' @param ... Parameters passed to simpleCache(). +#' @param ... Parameters passed to \code{\link{simpleCache}}. #' @export simpleCacheSharedGlobal = function(...) { simpleCache(..., cacheDir=getOption("RESOURCES.RCACHE"), loadEnvir=globalenv()) diff --git a/R/simpleCache.R b/R/simpleCache.R index 50cae1c..2605b45 100755 --- a/R/simpleCache.R +++ b/R/simpleCache.R @@ -48,7 +48,7 @@ NULL #' @param noload noload is useful for: you want to create the caches, but not #' load them if they aren't there (like a cache creation loop). #' @param cacheDir The directory where caches are saved (and loaded from). -#' Defaults to the global \code{\link[=setCacheDir]{RCACHE.DIR}} RCACHE.DIR variable +#' Defaults to the global \code{\link[=setCacheDir]{RCACHE.DIR}} variable #' @param cacheSubDir You can specify a subdirectory within the \code{cacheDir} #' variable. Defaults to \code{NULL}. #' @param assignToVariable By default, \code{simpleCache} assigns the cache to a diff --git a/R/storeCache.R b/R/storeCache.R index 0a1ffc6..b684b51 100644 --- a/R/storeCache.R +++ b/R/storeCache.R @@ -1,20 +1,20 @@ #' Stores as a cache an already-produced R object #' #' Sometimes you use significant computational power to create an object, but -#' you didn't cache it with simpleCache. Oops, maybe you wish you had, after the +#' you didn't cache it with \code{\link{simpleCache}}. Oops, maybe you wish you had, after the #' fact. This function lets you store an object in the environment so it could -#' be loaded by future calls to simpleCache. +#' be loaded by future calls to \code{simpleCache}. #' #' This can be used in interactive sessions, but could also be used for another #' use case: you have a complicated set of instructions (too much to pass as the -#' instruction argument to simpleCache), so you could just stick a call to -#' storeCache at the end. +#' instruction argument to \code{simpleCache}), so you could just stick a call to +#' \code{storeCache} at the end. #' #' @param cacheName Unique name for the cache (and R object to be cached). #' @param cacheDir The directory where caches are saved (and loaded from). -#' Defaults to the global RCACHE.DIR variable +#' Defaults to the global \code{\link[=setCacheDir]{RCACHE.DIR}} variable #' @param cacheSubDir You can specify a subdirectory within the cacheDir -#' variable. Defaults to NULL. +#' variable. Defaults to \code{NULL}. #' @param recreate Forces reconstruction of the cache #' @export #' @example diff --git a/man/loadCaches.Rd b/man/loadCaches.Rd index b247e1b..030100b 100644 --- a/man/loadCaches.Rd +++ b/man/loadCaches.Rd @@ -9,7 +9,7 @@ loadCaches(cacheNames, ...) \arguments{ \item{cacheNames}{Vector of caches to load.} -\item{...}{Additional parameters passed to simpleCache.} +\item{...}{Additional parameters passed to \code{\link{simpleCache}}.} } \description{ This function just takes a list of caches, and loads them. It's designed diff --git a/man/resetCacheSearchEnvironment.Rd b/man/resetCacheSearchEnvironment.Rd index d83900b..3369c77 100644 --- a/man/resetCacheSearchEnvironment.Rd +++ b/man/resetCacheSearchEnvironment.Rd @@ -2,10 +2,10 @@ % Please edit documentation in R/cacheDirectories.R \name{resetCacheSearchEnvironment} \alias{resetCacheSearchEnvironment} -\title{Sets global option of cache search environments to NULL.} +\title{Sets global option of cache search environments to \code{NULL}.} \usage{ resetCacheSearchEnvironment() } \description{ -Sets global option of cache search environments to NULL. +Sets global option of cache search environments to \code{NULL}. } diff --git a/man/setCacheDir.Rd b/man/setCacheDir.Rd index de719b4..4c3c969 100644 --- a/man/setCacheDir.Rd +++ b/man/setCacheDir.Rd @@ -3,7 +3,7 @@ \name{setCacheDir} \alias{setCacheDir} \title{Sets a global variable specifying the default cache directory for -simpleCache() calls.} +\code{\link{simpleCache}} calls.} \usage{ setCacheDir(cacheDir) } @@ -12,7 +12,7 @@ setCacheDir(cacheDir) } \description{ Sets a global variable specifying the default cache directory for -simpleCache() calls. +\code{\link{simpleCache}} calls. } \examples{ # choose location to store caches diff --git a/man/setSharedCacheDir.Rd b/man/setSharedCacheDir.Rd index 16abc12..9cdb4df 100644 --- a/man/setSharedCacheDir.Rd +++ b/man/setSharedCacheDir.Rd @@ -11,6 +11,6 @@ setSharedCacheDir(sharedCacheDir) } \description{ Sets global variable specifying the default cache directory for -simpleCacheShared() calls; this function is simply a helper alias for caching +\code{\link{simpleCacheShared}} calls; this function is simply a helper alias for caching results that will be used across projects. } diff --git a/man/simpleCache.Rd b/man/simpleCache.Rd index b1d6b73..50f28be 100644 --- a/man/simpleCache.Rd +++ b/man/simpleCache.Rd @@ -32,7 +32,7 @@ for evaluating the code in instruction.} load them if they aren't there (like a cache creation loop).} \item{cacheDir}{The directory where caches are saved (and loaded from). -Defaults to the global \code{\link[=setCacheDir]{RCACHE.DIR}} RCACHE.DIR variable} +Defaults to the global \code{\link[=setCacheDir]{RCACHE.DIR}} variable} \item{cacheSubDir}{You can specify a subdirectory within the \code{cacheDir} variable. Defaults to \code{NULL}.} diff --git a/man/simpleCacheGlobal.Rd b/man/simpleCacheGlobal.Rd index da705b2..019a939 100644 --- a/man/simpleCacheGlobal.Rd +++ b/man/simpleCacheGlobal.Rd @@ -9,7 +9,7 @@ ensures that the variables are loaded in the global environment.} simpleCacheGlobal(...) } \arguments{ -\item{...}{Parameters passed to simpleCache().} +\item{...}{Parameters passed to \code{\link{simpleCache}}.} } \description{ Helper alias for loading caches into the global environment. diff --git a/man/simpleCacheShared.Rd b/man/simpleCacheShared.Rd index ff0b21f..9061eab 100644 --- a/man/simpleCacheShared.Rd +++ b/man/simpleCacheShared.Rd @@ -7,7 +7,7 @@ simpleCacheShared(...) } \arguments{ -\item{...}{Parameters passed to simpleCache().} +\item{...}{Parameters passed to \code{\link{simpleCache}}.} } \description{ Helper alias for caching across experiments/people. diff --git a/man/simpleCacheSharedGlobal.Rd b/man/simpleCacheSharedGlobal.Rd index b3a06cb..802a788 100644 --- a/man/simpleCacheSharedGlobal.Rd +++ b/man/simpleCacheSharedGlobal.Rd @@ -7,7 +7,7 @@ simpleCacheSharedGlobal(...) } \arguments{ -\item{...}{Parameters passed to simpleCache().} +\item{...}{Parameters passed to \code{\link{simpleCache}}.} } \description{ Helper alias for loading shared caches into the global environment. diff --git a/man/storeCache.Rd b/man/storeCache.Rd index 76b5a66..306b21d 100644 --- a/man/storeCache.Rd +++ b/man/storeCache.Rd @@ -11,24 +11,24 @@ storeCache(cacheName, cacheDir = getOption("RCACHE.DIR"), \item{cacheName}{Unique name for the cache (and R object to be cached).} \item{cacheDir}{The directory where caches are saved (and loaded from). -Defaults to the global RCACHE.DIR variable} +Defaults to the global \code{\link[=setCacheDir]{RCACHE.DIR}} variable} \item{cacheSubDir}{You can specify a subdirectory within the cacheDir -variable. Defaults to NULL.} +variable. Defaults to \code{NULL}.} \item{recreate}{Forces reconstruction of the cache} } \description{ Sometimes you use significant computational power to create an object, but -you didn't cache it with simpleCache. Oops, maybe you wish you had, after the +you didn't cache it with \code{\link{simpleCache}}. Oops, maybe you wish you had, after the fact. This function lets you store an object in the environment so it could -be loaded by future calls to simpleCache. +be loaded by future calls to \code{simpleCache}. } \details{ This can be used in interactive sessions, but could also be used for another use case: you have a complicated set of instructions (too much to pass as the -instruction argument to simpleCache), so you could just stick a call to -storeCache at the end. +instruction argument to \code{simpleCache}), so you could just stick a call to +\code{storeCache} at the end. } \examples{ # choose location to store caches From d64c5daebcdfbd0bbbf842488bfd91f769df286b Mon Sep 17 00:00:00 2001 From: VP Nagraj Date: Mon, 4 Dec 2017 12:58:41 -0500 Subject: [PATCH 26/55] now listing highlights of exported functions in README --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index e19abc9..fb21d05 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,14 @@ paramount**. `simpleCache` assumes that your name for an object is a perfect identifier for that object; in other words, don't cache things that you plan to change. +### Highlights of exported functions + +- `simpleCache()`: Caches and reloads objects created based on instruction +- `listCaches()`: Liosts all of the caches available in the `cacheDir` +- `deleteCaches()`: Deletes cache(s) from the `cacheDir` +- `setCacheDir()`: Sets a global option for a cache directory so you don't have to specify one in each `simpleCache` call +- `viewCacheDirs()`: Views all of the `simpleCache` global options that have been set + ### Contributing `simpleCache` is licensed under the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause). Questions, feature requests and bug reports are welcome via the [issue queue](https://github.com/databio/simpleCache/issues). The maintainer will review pull requests and incorporate contributions at his discretion. From 470e33a91f637d1d66f28aeae6f8e4d01f5f30ea Mon Sep 17 00:00:00 2001 From: VP Nagraj Date: Tue, 5 Dec 2017 16:09:33 -0500 Subject: [PATCH 27/55] deleting enforceEdgeCharacter function altogether --- R/utility.R | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/R/utility.R b/R/utility.R index 036ffb1..9d73e40 100644 --- a/R/utility.R +++ b/R/utility.R @@ -9,25 +9,6 @@ # # These functions should probably remain interior to the package (not exported) # - -# enforceEdgeCharacter = function(string, prependChar="", appendChar="") { -# if (string=="" | is.null(string)) { -# return(string) -# } -# if(!is.null(appendChar)) { -# if (substr(string,nchar(string), nchar(string)) != appendChar) { # +1 ? -# string = paste0(string, appendChar); -# } -# } -# if (!is.null(prependChar)) { -# if (substr(string,1,1) != prependChar) { # +1 ? -# string = paste0(prependChar, string) -# } -# } -# return(string) -# } - - #' Determine if a cache file is sufficiently old to warrant refresh. #' #' \code{.tooOld} accepts a maximum cache age and checks for an option with From a47c29b07b07e16311010eda16d6f9cb44abe374 Mon Sep 17 00:00:00 2001 From: VP Nagraj Date: Tue, 5 Dec 2017 16:15:59 -0500 Subject: [PATCH 28/55] fixed typo and simpleCache description in README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index afa4587..5a15a65 100644 --- a/README.md +++ b/README.md @@ -83,8 +83,8 @@ change. ### Highlights of exported functions -- `simpleCache()`: Caches and reloads objects created based on instruction -- `listCaches()`: Liosts all of the caches available in the `cacheDir` +- `simpleCache()`: Creates and caches or reloads cached results of provided R instruction code +- `listCaches()`: Lists all of the caches available in the `cacheDir` - `deleteCaches()`: Deletes cache(s) from the `cacheDir` - `setCacheDir()`: Sets a global option for a cache directory so you don't have to specify one in each `simpleCache` call - `viewCacheDirs()`: Views all of the `simpleCache` global options that have been set From 53a1783f27630e4691688a95f16b61ea74204141 Mon Sep 17 00:00:00 2001 From: VP Nagraj Date: Wed, 6 Dec 2017 18:23:43 -0500 Subject: [PATCH 29/55] putting pkgdown.yml in R buildignore --- .Rbuildignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.Rbuildignore b/.Rbuildignore index af564cd..dd1977d 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -4,4 +4,5 @@ ^cran-comments.md$ ^CONDUCT\.md$ ^paper$ -.github \ No newline at end of file +.github +^_pkgdown\.yml$ From ed7ebd8ed6f3696b801cbfb4ae7cd0785b0d4db6 Mon Sep 17 00:00:00 2001 From: VP Nagraj Date: Wed, 6 Dec 2017 18:27:17 -0500 Subject: [PATCH 30/55] putting pkgdown.yaml in R buildignore --- .Rbuildignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.Rbuildignore b/.Rbuildignore index dd1977d..4ef4e99 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -5,4 +5,4 @@ ^CONDUCT\.md$ ^paper$ .github -^_pkgdown\.yml$ +^_pkgdown\.yaml$ From f53be706d20fae14e1550baf97e1a9e48fa9b8dc Mon Sep 17 00:00:00 2001 From: VP Nagraj Date: Wed, 6 Dec 2017 18:27:45 -0500 Subject: [PATCH 31/55] removing obsolete test --- tests/testthat/test_all.R | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/testthat/test_all.R b/tests/testthat/test_all.R index 928c086..fa1e294 100644 --- a/tests/testthat/test_all.R +++ b/tests/testthat/test_all.R @@ -21,9 +21,6 @@ test_that("notifications and messages as expected", { # error when buildEnvir includes "instruction" expect_error(simpleCache("normSample", { rnorm(5e3, 0,1) }, buildEnvir = list(instruction="foo"), recreate=TRUE, cacheDir = tempdir()), "Can't provide a variable named 'instruction' in buildEnvir") - # warning when instruction is not expression - expect_warning(simpleCache("normSample", instruction = "rnorm(5e3, 0,1)", cacheDir = tempdir(), recreate=TRUE)) - # error when instruction and buildDir are null expect_error(simpleCache("normSample", instruction = NULL, buildDir = NULL, cacheDir = tempdir(), recreate=TRUE)) From 4783cb78ab342854d29152dbe314e3ffe8024611 Mon Sep 17 00:00:00 2001 From: VP Nagraj Date: Wed, 6 Dec 2017 18:32:21 -0500 Subject: [PATCH 32/55] added utils:: to file_test to satisfy devtools::check() note --- R/utility.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/utility.R b/R/utility.R index 9d73e40..68f9d58 100644 --- a/R/utility.R +++ b/R/utility.R @@ -26,7 +26,7 @@ #' \code{getOption("MAX.CACHE.AGE")} if no age threshold is passed #' and that option exists; \code{FALSE} otherwise. .tooOld = function(pathCacheFile, lifespan=NULL) { - if (!file_test("-f", pathCacheFile)) { return(FALSE) } + if (!utils::file_test("-f", pathCacheFile)) { return(FALSE) } if (is.null(lifespan)) { lifespan = getOption("MAX.CACHE.AGE") } if (is.null(lifespan)) { return(FALSE) } cacheTime = file.info(pathCacheFile)$ctime From 5c2c6e52a9d7409dbb4d6b797748cceb80e71ca3 Mon Sep 17 00:00:00 2001 From: VP Nagraj Date: Wed, 6 Dec 2017 18:47:05 -0500 Subject: [PATCH 33/55] changed name of viewCacheDirs() to simpleCacheOptions() --- NAMESPACE | 2 +- R/cacheDirectories.R | 6 +++--- README.md | 2 +- man/loadCaches.Rd | 1 - man/simpleCache.Rd | 4 ++-- man/viewCacheDirs.Rd | 11 ----------- 6 files changed, 7 insertions(+), 19 deletions(-) delete mode 100644 man/viewCacheDirs.Rd diff --git a/NAMESPACE b/NAMESPACE index 38ae188..da5de29 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -10,7 +10,7 @@ export(setCacheDir) export(setSharedCacheDir) export(simpleCache) export(simpleCacheGlobal) +export(simpleCacheOptions) export(simpleCacheShared) export(simpleCacheSharedGlobal) export(storeCache) -export(viewCacheDirs) diff --git a/R/cacheDirectories.R b/R/cacheDirectories.R index 8f3f430..d07efd3 100644 --- a/R/cacheDirectories.R +++ b/R/cacheDirectories.R @@ -36,11 +36,11 @@ setCacheBuildDir = function(cacheBuildDir) { options(RBUILD.DIR=cacheBuildDir) } -#' View cache directories +#' View simpleCache options #' -#' Views cache directory global variables +#' Views simpleCache global variables #' @export -viewCacheDirs = function() { +simpleCacheOptions = function() { message("RESOURCES.RCACHE:\t", getOption("RESOURCES.RCACHE")) message("RCACHE.DIR:\t", getOption("RCACHE.DIR")) message("RBUILD.DIR:\t", getOption("RBUILD.DIR")) diff --git a/README.md b/README.md index 5a15a65..f6118b5 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ change. - `listCaches()`: Lists all of the caches available in the `cacheDir` - `deleteCaches()`: Deletes cache(s) from the `cacheDir` - `setCacheDir()`: Sets a global option for a cache directory so you don't have to specify one in each `simpleCache` call -- `viewCacheDirs()`: Views all of the `simpleCache` global options that have been set +- `simpleCacheOptions()`: Views all of the `simpleCache` global options that have been set ### Contributing diff --git a/man/loadCaches.Rd b/man/loadCaches.Rd index 0a2da28..e4d8d64 100644 --- a/man/loadCaches.Rd +++ b/man/loadCaches.Rd @@ -9,7 +9,6 @@ loadCaches(cacheNames, loadEnvir = NULL, ...) \arguments{ \item{cacheNames}{Vector of caches to load.} - \item{loadEnvir}{Environment into which to load each cache.} \item{...}{Additional parameters passed to simpleCache.} diff --git a/man/simpleCache.Rd b/man/simpleCache.Rd index cedc099..ec61b3f 100644 --- a/man/simpleCache.Rd +++ b/man/simpleCache.Rd @@ -40,7 +40,8 @@ variable. Defaults to \code{NULL}.} \item{timer}{Report how long it took to create the cache?} \item{buildDir}{Location of Build files (files with instructions for use If -the instructions argument is not provided). Defaults to \code{\link[=setCacheBuildDir]{RBUILD.DIR}} global option.} +the instructions argument is not provided). Defaults to RBUILD.DIR +global option.} \item{assignToVariable}{By default, \code{simpleCache} assigns the cache to a variable named \code{cacheName}; you can overrule that here.} @@ -52,7 +53,6 @@ variable? Defaults to \code{\link[base]{parent.frame}}.} cache.} \item{nofail}{By default, simpleCache throws an error if the instructions - fail. Use this option to convert this error into a warning. No cache will be created, but simpleCache will not then hard-stop your processing. This is useful, for example, if you are creating a bunch of caches and it's ok diff --git a/man/viewCacheDirs.Rd b/man/viewCacheDirs.Rd deleted file mode 100644 index 4eac757..0000000 --- a/man/viewCacheDirs.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/cacheDirectories.R -\name{viewCacheDirs} -\alias{viewCacheDirs} -\title{View cache directories} -\usage{ -viewCacheDirs() -} -\description{ -Views cache directory global variables -} From 37591a2ed8c60d77d3c9bde90f2eca794b36d04d Mon Sep 17 00:00:00 2001 From: VP Nagraj Date: Wed, 6 Dec 2017 18:48:40 -0500 Subject: [PATCH 34/55] updated change log and added loose rd files --- NEWS | 1 + man/dot-tooOld.Rd | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 man/dot-tooOld.Rd diff --git a/NEWS b/NEWS index 707e9e0..920eca4 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file. ## [0.3.2] -- Unreleased - remove unnecessary parse argument to simpleCache() + - viewCacheDirs() renamed to simpleCacheOptions() ## [0.3.1] -- 2017-08-21 diff --git a/man/dot-tooOld.Rd b/man/dot-tooOld.Rd new file mode 100644 index 0000000..8f6091c --- /dev/null +++ b/man/dot-tooOld.Rd @@ -0,0 +1,28 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utility.R +\name{.tooOld} +\alias{.tooOld} +\title{Determine if a cache file is sufficiently old to warrant refresh.} +\usage{ +.tooOld(pathCacheFile, lifespan = NULL) +} +\arguments{ +\item{pathCacheFile}{Path to file to ask about staleness.} + +\item{lifespan}{Maximum file age before it's "stale."} +} +\value{ +\code{TRUE} if the file exists and its age exceeds + \code{lifespan} if given or + \code{getOption("MAX.CACHE.AGE")} if no age threshold is passed + and that option exists; \code{FALSE} otherwise. +} +\description{ +\code{.tooOld} accepts a maximum cache age and checks for an option with +that setting under \code{MAX.CACHE.AGE} if such an argument isn't passed. +If the indicated file exists and is older than the threshold passed or +set as an option, the file is deemed "stale." If an age threshold is +provided, no check for an option is performed. If the file does not +exist or there's not an age threshold directly passed or set as an option, +the result is \code{FALSE}. +} From d6d21f0c478339b118dd4c53976b22f952d321ea Mon Sep 17 00:00:00 2001 From: VP Nagraj Date: Wed, 6 Dec 2017 18:50:20 -0500 Subject: [PATCH 35/55] changed viewCacheDirs name in tests as well --- man/simpleCacheOptions.Rd | 11 +++++++++++ tests/testthat/test_all.R | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 man/simpleCacheOptions.Rd diff --git a/man/simpleCacheOptions.Rd b/man/simpleCacheOptions.Rd new file mode 100644 index 0000000..f6c9460 --- /dev/null +++ b/man/simpleCacheOptions.Rd @@ -0,0 +1,11 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cacheDirectories.R +\name{simpleCacheOptions} +\alias{simpleCacheOptions} +\title{View simpleCache options} +\usage{ +simpleCacheOptions() +} +\description{ +Views simpleCache global variables +} diff --git a/tests/testthat/test_all.R b/tests/testthat/test_all.R index fa1e294..949dc66 100644 --- a/tests/testthat/test_all.R +++ b/tests/testthat/test_all.R @@ -107,7 +107,7 @@ test_that("option setting works", { addCacheSearchEnvironment("cacheEnv") # capture output and check - options_out <- capture_messages(viewCacheDirs()) + options_out <- capture_messages(simpleCacheOptions()) expect_true(grepl(tempdir(), options_out[1])) expect_true(grepl(tempdir(), options_out[2])) @@ -118,7 +118,7 @@ test_that("option setting works", { resetCacheSearchEnvironment() # check to make sure it is gone - options_out <- capture_messages(viewCacheDirs()) + options_out <- capture_messages(simpleCacheOptions()) expect_true(!grepl("cacheEnv", options_out[4])) }) From 80d83e9540b24ebbd8d9ac201551baaad5fac764 Mon Sep 17 00:00:00 2001 From: nsheff Date: Mon, 18 Dec 2017 11:21:24 -0500 Subject: [PATCH 36/55] reorder readme --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f6118b5..7568fd4 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,14 @@ simpleCache("normSample", { rnorm(1e7, 0,1) }) caches on any cluster resource manager. -------------------------------------------------------------------------------- +### Highlights of exported functions + +- `simpleCache()`: Creates and caches or reloads cached results of provided R instruction code +- `listCaches()`: Lists all of the caches available in the `cacheDir` +- `deleteCaches()`: Deletes cache(s) from the `cacheDir` +- `setCacheDir()`: Sets a global option for a cache directory so you don't have to specify one in each `simpleCache` call +- `simpleCacheOptions()`: Views all of the `simpleCache` global options that have been set + ### simpleCache Philosophy The use case I had in mind for `simpleCache` is that you find yourself @@ -81,14 +89,6 @@ paramount**. `simpleCache` assumes that your name for an object is a perfect identifier for that object; in other words, don't cache things that you plan to change. -### Highlights of exported functions - -- `simpleCache()`: Creates and caches or reloads cached results of provided R instruction code -- `listCaches()`: Lists all of the caches available in the `cacheDir` -- `deleteCaches()`: Deletes cache(s) from the `cacheDir` -- `setCacheDir()`: Sets a global option for a cache directory so you don't have to specify one in each `simpleCache` call -- `simpleCacheOptions()`: Views all of the `simpleCache` global options that have been set - ### Contributing `simpleCache` is licensed under the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause). Questions, feature requests and bug reports are welcome via the [issue queue](https://github.com/databio/simpleCache/issues). The maintainer will review pull requests and incorporate contributions at his discretion. From ca4ac257ce4842202de0120919d4e59b410dab92 Mon Sep 17 00:00:00 2001 From: nsheff Date: Mon, 18 Dec 2017 13:13:25 -0500 Subject: [PATCH 37/55] version and changelog --- DESCRIPTION | 2 +- NEWS | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index ef5c2b9..eaedecd 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: simpleCache -Version: 0.3.2 +Version: 0.4.0 Date: 2017-08-21 Title: Simply Caching R Objects Description: Provides intuitive functions for caching R objects, encouraging diff --git a/NEWS b/NEWS index 920eca4..2531bbc 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,9 @@ # Change log All notable changes to this project will be documented in this file. -## [0.3.2] -- Unreleased +## [0.4.0] -- Unreleased + - adds a lifespan arg to simpleCache() to create auto-expiring caches - remove unnecessary parse argument to simpleCache() - viewCacheDirs() renamed to simpleCacheOptions() From 2446a90c9272bd977ce4490189af61e84b7db8f1 Mon Sep 17 00:00:00 2001 From: nsheff Date: Mon, 18 Dec 2017 14:22:06 -0500 Subject: [PATCH 38/55] Specify arg types; See #30 --- R/simpleCache.R | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/R/simpleCache.R b/R/simpleCache.R index b7b146c..a05e479 100755 --- a/R/simpleCache.R +++ b/R/simpleCache.R @@ -38,45 +38,51 @@ NULL #' environment variables you use in your instruction code. You can use this #' using the parameter buildEnvir (just provide a list of named variables). #' -#' @param cacheName Unique name for the cache. Be careful. -#' @param instruction Quoted R code to be evaluated. The returned value of this +#' @param cacheName A character vector for a unique name for the cache. Be careful. +#' @param instruction R expression (bracketed) to be evaluated. The returned value of this #' code is what will be cached under the cacheName. -#' @param buildEnvir You may choose to provide additional variables necessary -#' for evaluating the code in instruction. -#' @param reload forces re-loading the cache, even if it exists in the env. -#' @param recreate forces reconstruction of the cache -#' @param noload noload is useful for: you want to create the caches, but not -#' load them if they aren't there (like a cache creation loop). -#' @param cacheDir The directory where caches are saved (and loaded from). -#' Defaults to the global \code{\link[=setCacheDir]{RCACHE.DIR}} variable -#' @param cacheSubDir You can specify a subdirectory within the \code{cacheDir} -#' variable. Defaults to \code{NULL}. -#' @param assignToVariable By default, \code{simpleCache} assigns the cache to a +#' @param buildEnvir An environment (or list) providing additional variables +#' necessary for evaluating the code in instruction. +#' @param reload Logical indicating whether to force re-loading the cache, +#' even if it exists in the env. +#' @param recreate Logical indicating whether to force reconstruction of the +#' cache +#' @param noload Logical indicating whether to create but not load the cache. +#' noload is useful for: you want to create the caches, but not load (like a +#' cache creation loop). +#' @param cacheDir Character vector specifying the directory where caches are +#' saved (and loaded from). Defaults to the variable set by +#' \code{\link[=setCacheDir]{setCacheDir()}}. +#' @param cacheSubDir Character vector specifying a subdirectory within the +#' \code{cacheDir} variable. Defaults to \code{NULL}. +#' @param assignToVariable Character vector for a variable name to load the +#' cache into. By default, \code{simpleCache} assigns the cache to a #' variable named \code{cacheName}; you can overrule that here. -#' @param loadEnvir Into which environment would you like to load the -#' variable? Defaults to \code{\link[base]{parent.frame}}. +#' @param loadEnvir An environment. Into which environment would you like to +#' load the variable? Defaults to \code{\link[base]{parent.frame}}. #' @param searchEnvir a vector of environments to search for the already loaded #' cache. -#' @param timer Report how long it took to create the cache? +#' @param timer Logical indicating whether to report how long it took to create +#' the cache. #' @param buildDir Location of Build files (files with instructions for use If #' the instructions argument is not provided). Defaults to RBUILD.DIR #' global option. #' @param nofail By default, simpleCache throws an error if the instructions #' fail. Use this option to convert this error into a warning. No cache will #' be created, but simpleCache will not then hard-stop your processing. This -#' is useful, for example, if you are creating a bunch of caches and it's ok -#' if some of them do not complete. +#' is useful, for example, if you are creating a bunch of caches (for +#' example using \code{lapply}) and it's ok if some of them do not complete. #' @param batchRegistry A \code{batchtools} registry object (built with #' \code{\link[batchtools]{makeRegistry}}). If provided, this cache will be created on #' the cluster using your batchtools configuration #' @param batchResources A list of variables to provide to batchtools for #' cluster resource managers. Used as the \code{res} argument to #' \code{\link[batchtools]{batchMap}} +#' @param lifespan Numeric specifying the maximum age of cache, in days, to +#' allow before automatically triggering \code{recreate=TRUE}. #' @param pepSettings Experimental untested feature. #' @param ignoreLock Internal parameter used for batch job submission; don't #' touch. -#' @param lifespan Maximum age of cache, in days, to allow before -#' automatically triggering \code{recreate=TRUE}. #' @export #' @example #' R/examples/example.R From 54ecb6e900ad0d1d46f3ece5c9d706a591f466c2 Mon Sep 17 00:00:00 2001 From: VP Nagraj Date: Mon, 18 Dec 2017 14:26:26 -0500 Subject: [PATCH 39/55] package level doc now has alias at simpleCache-package --- R/simpleCache.R | 4 ++-- man/simpleCache-package.Rd | 32 ++++++++++++++++++++++++++++++++ man/simpleCache.Rd | 11 +---------- 3 files changed, 35 insertions(+), 12 deletions(-) create mode 100644 man/simpleCache-package.Rd diff --git a/R/simpleCache.R b/R/simpleCache.R index b7b146c..0fc04fa 100755 --- a/R/simpleCache.R +++ b/R/simpleCache.R @@ -4,9 +4,9 @@ #' #' @references \url{https://github.com/databio/simpleCache} #' @docType package -#' @name simpleCache #' @author Nathan Sheffield -NULL +#' @aliases simpleCache-package +"_PACKAGE" ################################################################################ diff --git a/man/simpleCache-package.Rd b/man/simpleCache-package.Rd new file mode 100644 index 0000000..7f2a86a --- /dev/null +++ b/man/simpleCache-package.Rd @@ -0,0 +1,32 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/simpleCache.R +\docType{package} +\name{simpleCache-package} +\alias{simpleCache-package} +\alias{_PACKAGE} +\title{Provides intuitive functions for caching R objects, encouraging faster +reproducible and restartable R analysis} +\description{ +Provides intuitive functions for caching R objects, encouraging +reproducible, restartable, and distributed R analysis. The user selects a +location to store caches, and then provides nothing more than a cache name +and instructions (R code) for how to produce the R object. Also +provides some advanced options like environment assignments, recreating or +reloading caches, and cluster compute bindings (using the 'batchtools' +package) making it flexible enough for use in large-scale data analysis +projects. +} +\references{ +\url{https://github.com/databio/simpleCache} +} +\seealso{ +Useful links: +\itemize{ + \item \url{https://www.github.com/databio/simpleCache} + \item Report bugs at \url{https://www.github.com/databio/simpleCache} +} + +} +\author{ +Nathan Sheffield +} diff --git a/man/simpleCache.Rd b/man/simpleCache.Rd index ec61b3f..8ad7cbc 100644 --- a/man/simpleCache.Rd +++ b/man/simpleCache.Rd @@ -1,11 +1,8 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/simpleCache.R -\docType{package} \name{simpleCache} \alias{simpleCache} -\alias{simpleCache-package} -\title{Provides intuitive functions for caching R objects, encouraging faster -reproducible and restartable R analysis} +\title{Create a new cache or load a previously created cache.} \usage{ simpleCache(cacheName, instruction = NULL, buildEnvir = NULL, reload = FALSE, recreate = FALSE, noload = FALSE, @@ -125,9 +122,3 @@ simpleCache("normSample") # load multiples caches loadCaches(c("normSample", "normSample2"), reload=TRUE) } -\references{ -\url{https://github.com/databio/simpleCache} -} -\author{ -Nathan Sheffield -} From 8c5ca60e161fe9dbbde52e59badce0cd9ef0825e Mon Sep 17 00:00:00 2001 From: nsheff Date: Mon, 18 Dec 2017 14:40:30 -0500 Subject: [PATCH 40/55] fix term braces --- R/simpleCache.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/simpleCache.R b/R/simpleCache.R index a05e479..f71aca4 100755 --- a/R/simpleCache.R +++ b/R/simpleCache.R @@ -39,7 +39,7 @@ NULL #' using the parameter buildEnvir (just provide a list of named variables). #' #' @param cacheName A character vector for a unique name for the cache. Be careful. -#' @param instruction R expression (bracketed) to be evaluated. The returned value of this +#' @param instruction R expression (in braces) to be evaluated. The returned value of this #' code is what will be cached under the cacheName. #' @param buildEnvir An environment (or list) providing additional variables #' necessary for evaluating the code in instruction. From cfc6838a8471a68f50996ad57ec072ba687ce851 Mon Sep 17 00:00:00 2001 From: Nathan Sheffield Date: Tue, 19 Dec 2017 07:40:53 -0500 Subject: [PATCH 41/55] Update README.md --- README.md | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 7568fd4..faf1a06 100644 --- a/README.md +++ b/README.md @@ -26,28 +26,16 @@ be installed as usual: install.packages("simpleCache") ``` -If you like, you may install the development version directly from github with -devtools - -``` -devtools::install_github("databio/simpleCache") -``` - -To install a local copy: -``` -packageFolder = "~/R/simpleCache"; install.packages(packageFolder, repos=NULL) -``` - -------------------------------------------------------------------------------- ### Running simpleCache -`simpleCache` comes with a single primary function that will do almost +`simpleCache` comes with a single primary function (`simpleCache()`) that will do almost everything you need. In short, you run it with a few lines like this: ``` library(simpleCache) setCacheDir(tempdir()) -simpleCache("normSample", { rnorm(1e7, 0,1) }, recreate=TRUE) +simpleCache("normSample", { rnorm(1e7, 0,1) }, recreate=TRUE) simpleCache("normSample", { rnorm(1e7, 0,1) }) ``` From 69effbcf7bdda953ab41de3e63d1b6bf6fe0e055 Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 20 Dec 2017 11:08:42 -0500 Subject: [PATCH 42/55] delay cache recreation --- tests/testthat/test_cache_lifespan.R | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/testthat/test_cache_lifespan.R b/tests/testthat/test_cache_lifespan.R index b85aa01..b1c9851 100644 --- a/tests/testthat/test_cache_lifespan.R +++ b/tests/testthat/test_cache_lifespan.R @@ -42,6 +42,7 @@ my_test_that("Cache file is replaced if no lifespan is specified and recreate=TR expect_equal(1, countCacheItems()) fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") t0 = file.info(fp)$ctime + Sys.sleep(0.1) mySimpleCache("testDF", recreate=TRUE, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime @@ -68,6 +69,7 @@ my_test_that("Cache is replaced if older than explicit lifespan", { fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") expect_equal(1, countCacheItems()) t0 = file.info(fp)$ctime + Sys.sleep(0.1) mySimpleCache("testDF", lifespan=0, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime @@ -81,6 +83,7 @@ my_test_that("Cache is replaced if recreate=TRUE even if cache is fresh", { fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") expect_equal(1, countCacheItems()) t0 = file.info(fp)$ctime + Sys.sleep(0.1) mySimpleCache("testDF", recreate=TRUE, lifespan=0, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime From 9e9c38b6c0eff6e5409a5ee54f14270cf5246ce3 Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 20 Dec 2017 12:23:24 -0500 Subject: [PATCH 43/55] remove unnecessary conditional on recreation flag --- R/simpleCache.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/simpleCache.R b/R/simpleCache.R index e48fdd4..6a08f61 100755 --- a/R/simpleCache.R +++ b/R/simpleCache.R @@ -144,7 +144,7 @@ simpleCache = function(cacheName, instruction=NULL, buildEnvir=NULL, ret = NULL # The default, in case the cache construction fails. - if (!recreate && .tooOld(cacheFile, lifespan)) { + if (.tooOld(cacheFile, lifespan)) { message(sprintf( "Stale cache: '%s' (age > %d day(s))", cacheFile, lifespan)) recreate = TRUE From 06d92242aa86e5a067218c03de809b18c66418a5 Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 20 Dec 2017 12:27:19 -0500 Subject: [PATCH 44/55] try slightly longer delay --- tests/testthat/test_cache_lifespan.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/testthat/test_cache_lifespan.R b/tests/testthat/test_cache_lifespan.R index b1c9851..4f937da 100644 --- a/tests/testthat/test_cache_lifespan.R +++ b/tests/testthat/test_cache_lifespan.R @@ -42,7 +42,7 @@ my_test_that("Cache file is replaced if no lifespan is specified and recreate=TR expect_equal(1, countCacheItems()) fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") t0 = file.info(fp)$ctime - Sys.sleep(0.1) + Sys.sleep(0.25) mySimpleCache("testDF", recreate=TRUE, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime @@ -69,7 +69,7 @@ my_test_that("Cache is replaced if older than explicit lifespan", { fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") expect_equal(1, countCacheItems()) t0 = file.info(fp)$ctime - Sys.sleep(0.1) + Sys.sleep(0.25) mySimpleCache("testDF", lifespan=0, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime @@ -83,7 +83,7 @@ my_test_that("Cache is replaced if recreate=TRUE even if cache is fresh", { fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") expect_equal(1, countCacheItems()) t0 = file.info(fp)$ctime - Sys.sleep(0.1) + Sys.sleep(0.25) mySimpleCache("testDF", recreate=TRUE, lifespan=0, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime From da7d11de1225127821cac6d589f9999935735e02 Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 20 Dec 2017 12:47:17 -0500 Subject: [PATCH 45/55] explanations and cleaner handling of testdir --- tests/testthat/helper-lifespan.R | 3 ++- tests/testthat/test_cache_lifespan.R | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/testthat/helper-lifespan.R b/tests/testthat/helper-lifespan.R index 79a3ce9..1d43044 100644 --- a/tests/testthat/helper-lifespan.R +++ b/tests/testthat/helper-lifespan.R @@ -14,7 +14,8 @@ lifespanTestsTmpdir = function() { file.path(tempdir(), "lifespan") } # Establish a temp folder and set the cache home location to it. setupLSTest = function() { - dir.create(lifespanTestsTmpdir()) + testdir = lifespanTestsTmpdir() + if (!file.test("-d", testdir)) { dir.create(testdir) } setCacheDir(lifespanTestsTmpdir()) } diff --git a/tests/testthat/test_cache_lifespan.R b/tests/testthat/test_cache_lifespan.R index 4f937da..c8c465b 100644 --- a/tests/testthat/test_cache_lifespan.R +++ b/tests/testthat/test_cache_lifespan.R @@ -42,7 +42,7 @@ my_test_that("Cache file is replaced if no lifespan is specified and recreate=TR expect_equal(1, countCacheItems()) fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") t0 = file.info(fp)$ctime - Sys.sleep(0.25) + Sys.sleep(0.25) # Delay so that our time comparison can work. mySimpleCache("testDF", recreate=TRUE, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime @@ -69,7 +69,7 @@ my_test_that("Cache is replaced if older than explicit lifespan", { fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") expect_equal(1, countCacheItems()) t0 = file.info(fp)$ctime - Sys.sleep(0.25) + Sys.sleep(0.25) # Time difference comparison reliability. mySimpleCache("testDF", lifespan=0, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime @@ -83,8 +83,8 @@ my_test_that("Cache is replaced if recreate=TRUE even if cache is fresh", { fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") expect_equal(1, countCacheItems()) t0 = file.info(fp)$ctime - Sys.sleep(0.25) - mySimpleCache("testDF", recreate=TRUE, lifespan=0, instruction={ buildTestFrame() }) + Sys.sleep(0.25) # Time difference comparison reliability. + mySimpleCache("testDF", recreate=TRUE, lifespan=1, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime expect_true(t1 > t0) From 2e2191ef456596b1d8d9ddd918e35752324b6bfa Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 20 Dec 2017 12:48:12 -0500 Subject: [PATCH 46/55] fix function name --- tests/testthat/helper-lifespan.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/helper-lifespan.R b/tests/testthat/helper-lifespan.R index 1d43044..08ab2b7 100644 --- a/tests/testthat/helper-lifespan.R +++ b/tests/testthat/helper-lifespan.R @@ -15,7 +15,7 @@ lifespanTestsTmpdir = function() { file.path(tempdir(), "lifespan") } # Establish a temp folder and set the cache home location to it. setupLSTest = function() { testdir = lifespanTestsTmpdir() - if (!file.test("-d", testdir)) { dir.create(testdir) } + if (!file_test("-d", testdir)) { dir.create(testdir) } setCacheDir(lifespanTestsTmpdir()) } From 653c2d12323000c3c0996a54796962956a8fd987 Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 20 Dec 2017 12:49:44 -0500 Subject: [PATCH 47/55] try nonsense value --- tests/testthat/test_cache_lifespan.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test_cache_lifespan.R b/tests/testthat/test_cache_lifespan.R index c8c465b..23c5128 100644 --- a/tests/testthat/test_cache_lifespan.R +++ b/tests/testthat/test_cache_lifespan.R @@ -70,7 +70,7 @@ my_test_that("Cache is replaced if older than explicit lifespan", { expect_equal(1, countCacheItems()) t0 = file.info(fp)$ctime Sys.sleep(0.25) # Time difference comparison reliability. - mySimpleCache("testDF", lifespan=0, instruction={ buildTestFrame() }) + mySimpleCache("testDF", lifespan=-1, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime expect_true(t1 > t0) From 63eacb0207ac235fd0b777ecccd6bcb01855aea1 Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 20 Dec 2017 12:51:48 -0500 Subject: [PATCH 48/55] revert to reasonable value --- tests/testthat/test_cache_lifespan.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test_cache_lifespan.R b/tests/testthat/test_cache_lifespan.R index 23c5128..467020a 100644 --- a/tests/testthat/test_cache_lifespan.R +++ b/tests/testthat/test_cache_lifespan.R @@ -84,7 +84,7 @@ my_test_that("Cache is replaced if recreate=TRUE even if cache is fresh", { expect_equal(1, countCacheItems()) t0 = file.info(fp)$ctime Sys.sleep(0.25) # Time difference comparison reliability. - mySimpleCache("testDF", recreate=TRUE, lifespan=1, instruction={ buildTestFrame() }) + mySimpleCache("testDF", recreate=TRUE, lifespan=0, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime expect_true(t1 > t0) From bae833fe094a965d5f09bc9af5b1cf412f5f4807 Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 20 Dec 2017 13:24:40 -0500 Subject: [PATCH 49/55] make direct assertions about time difference --- tests/testthat/test_cache_lifespan.R | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/testthat/test_cache_lifespan.R b/tests/testthat/test_cache_lifespan.R index 467020a..2e7ffa1 100644 --- a/tests/testthat/test_cache_lifespan.R +++ b/tests/testthat/test_cache_lifespan.R @@ -84,6 +84,9 @@ my_test_that("Cache is replaced if recreate=TRUE even if cache is fresh", { expect_equal(1, countCacheItems()) t0 = file.info(fp)$ctime Sys.sleep(0.25) # Time difference comparison reliability. + deltaT = difftime(Sys.time(), file.info(fp)$ctime, units="days") + expect_true(deltaT > 0) + expect_true(deltaT < 1) mySimpleCache("testDF", recreate=TRUE, lifespan=0, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime From 89faefad84e9b51a8a8f11dfdb0f8b9fcd499e34 Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 20 Dec 2017 13:29:21 -0500 Subject: [PATCH 50/55] revert to reasonable value --- tests/testthat/test_cache_lifespan.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test_cache_lifespan.R b/tests/testthat/test_cache_lifespan.R index 2e7ffa1..9603f2d 100644 --- a/tests/testthat/test_cache_lifespan.R +++ b/tests/testthat/test_cache_lifespan.R @@ -70,7 +70,7 @@ my_test_that("Cache is replaced if older than explicit lifespan", { expect_equal(1, countCacheItems()) t0 = file.info(fp)$ctime Sys.sleep(0.25) # Time difference comparison reliability. - mySimpleCache("testDF", lifespan=-1, instruction={ buildTestFrame() }) + mySimpleCache("testDF", lifespan=0, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime expect_true(t1 > t0) From b32b8dbda65625786d012f1265cc22fb3ca7289a Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 20 Dec 2017 13:38:15 -0500 Subject: [PATCH 51/55] file existence tests --- tests/testthat/test_cache_lifespan.R | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/testthat/test_cache_lifespan.R b/tests/testthat/test_cache_lifespan.R index 9603f2d..bc96303 100644 --- a/tests/testthat/test_cache_lifespan.R +++ b/tests/testthat/test_cache_lifespan.R @@ -38,9 +38,11 @@ my_test_that("Cache file isn't replaced if no lifespan is specified and recreate # Another sort of control my_test_that("Cache file is replaced if no lifespan is specified and recreate=TRUE", { expect_equal(0, countCacheItems()) + fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") + expect_false(file_test("-f", fp)) mySimpleCache("testDF", instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) - fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") + expect_true(file_test("-f", fp)) t0 = file.info(fp)$ctime Sys.sleep(0.25) # Delay so that our time comparison can work. mySimpleCache("testDF", recreate=TRUE, instruction={ buildTestFrame() }) @@ -52,9 +54,11 @@ my_test_that("Cache file is replaced if no lifespan is specified and recreate=TR # Specificity my_test_that("Cache remains unchanged if younger than explicit lifespan", { expect_equal(0, countCacheItems()) + fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") + expect_false(file_test("-f", fp)) mySimpleCache("testDF", instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) - fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") + expect_true(file_test("-f", fp)) t0 = file.info(fp)$ctime mySimpleCache("testDF", lifespan=0.5, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) @@ -65,9 +69,11 @@ my_test_that("Cache remains unchanged if younger than explicit lifespan", { # Sensitivity my_test_that("Cache is replaced if older than explicit lifespan", { expect_equal(0, countCacheItems()) - mySimpleCache("testDF", instruction={ buildTestFrame() }) fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") + expect_false(file_test("-f", fp)) + mySimpleCache("testDF", instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) + expect_true(file_test("-f", fp)) t0 = file.info(fp)$ctime Sys.sleep(0.25) # Time difference comparison reliability. mySimpleCache("testDF", lifespan=0, instruction={ buildTestFrame() }) @@ -81,12 +87,10 @@ my_test_that("Cache is replaced if recreate=TRUE even if cache is fresh", { expect_equal(0, countCacheItems()) mySimpleCache("testDF", instruction={ buildTestFrame() }) fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") + expect_true(file_test("-f", fp)) expect_equal(1, countCacheItems()) t0 = file.info(fp)$ctime Sys.sleep(0.25) # Time difference comparison reliability. - deltaT = difftime(Sys.time(), file.info(fp)$ctime, units="days") - expect_true(deltaT > 0) - expect_true(deltaT < 1) mySimpleCache("testDF", recreate=TRUE, lifespan=0, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime From d49c17ed0b1620769df1c4ba783c3955079f9802 Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 20 Dec 2017 13:40:05 -0500 Subject: [PATCH 52/55] remove unused tmpdir function --- tests/testthat/helper-lifespan.R | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/testthat/helper-lifespan.R b/tests/testthat/helper-lifespan.R index 08ab2b7..3e578f5 100644 --- a/tests/testthat/helper-lifespan.R +++ b/tests/testthat/helper-lifespan.R @@ -18,6 +18,3 @@ setupLSTest = function() { if (!file_test("-d", testdir)) { dir.create(testdir) } setCacheDir(lifespanTestsTmpdir()) } - -# Check that a path is in the temporary folder. -.inTmpdir = function(path) { substr(path, 1, length(tempdir())) == tempdir() } From f00ff31ec3a5c1f27b319b37d457fe6b9b8f631f Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 20 Dec 2017 13:42:39 -0500 Subject: [PATCH 53/55] longer sleep for time comparison reliability --- tests/testthat/test_cache_lifespan.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/testthat/test_cache_lifespan.R b/tests/testthat/test_cache_lifespan.R index bc96303..0ba778b 100644 --- a/tests/testthat/test_cache_lifespan.R +++ b/tests/testthat/test_cache_lifespan.R @@ -44,7 +44,7 @@ my_test_that("Cache file is replaced if no lifespan is specified and recreate=TR expect_equal(1, countCacheItems()) expect_true(file_test("-f", fp)) t0 = file.info(fp)$ctime - Sys.sleep(0.25) # Delay so that our time comparison can work. + Sys.sleep(0.5) # Delay so that our time comparison can work. mySimpleCache("testDF", recreate=TRUE, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime @@ -75,7 +75,7 @@ my_test_that("Cache is replaced if older than explicit lifespan", { expect_equal(1, countCacheItems()) expect_true(file_test("-f", fp)) t0 = file.info(fp)$ctime - Sys.sleep(0.25) # Time difference comparison reliability. + Sys.sleep(0.5) # Time difference comparison reliability. mySimpleCache("testDF", lifespan=0, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime @@ -90,7 +90,7 @@ my_test_that("Cache is replaced if recreate=TRUE even if cache is fresh", { expect_true(file_test("-f", fp)) expect_equal(1, countCacheItems()) t0 = file.info(fp)$ctime - Sys.sleep(0.25) # Time difference comparison reliability. + Sys.sleep(0.5) # Time difference comparison reliability. mySimpleCache("testDF", recreate=TRUE, lifespan=0, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime From bc62a1afd345047dcc002187c26c689baf0f79c1 Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 20 Dec 2017 13:43:52 -0500 Subject: [PATCH 54/55] more sleep time --- tests/testthat/test_cache_lifespan.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/testthat/test_cache_lifespan.R b/tests/testthat/test_cache_lifespan.R index 0ba778b..9b3f255 100644 --- a/tests/testthat/test_cache_lifespan.R +++ b/tests/testthat/test_cache_lifespan.R @@ -44,7 +44,7 @@ my_test_that("Cache file is replaced if no lifespan is specified and recreate=TR expect_equal(1, countCacheItems()) expect_true(file_test("-f", fp)) t0 = file.info(fp)$ctime - Sys.sleep(0.5) # Delay so that our time comparison can work. + Sys.sleep(1) # Delay so that our time comparison can work. mySimpleCache("testDF", recreate=TRUE, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime @@ -75,7 +75,7 @@ my_test_that("Cache is replaced if older than explicit lifespan", { expect_equal(1, countCacheItems()) expect_true(file_test("-f", fp)) t0 = file.info(fp)$ctime - Sys.sleep(0.5) # Time difference comparison reliability. + Sys.sleep(1) # Time difference comparison reliability. mySimpleCache("testDF", lifespan=0, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime @@ -90,7 +90,7 @@ my_test_that("Cache is replaced if recreate=TRUE even if cache is fresh", { expect_true(file_test("-f", fp)) expect_equal(1, countCacheItems()) t0 = file.info(fp)$ctime - Sys.sleep(0.5) # Time difference comparison reliability. + Sys.sleep(1) # Time difference comparison reliability. mySimpleCache("testDF", recreate=TRUE, lifespan=0, instruction={ buildTestFrame() }) expect_equal(1, countCacheItems()) t1 = file.info(fp)$ctime From 2e824cb65e79848ac26c4ad830b6f54606f4173a Mon Sep 17 00:00:00 2001 From: Vince Reuter Date: Wed, 20 Dec 2017 13:58:01 -0500 Subject: [PATCH 55/55] tests regarding option --- tests/testthat/test_cache_lifespan.R | 32 +++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test_cache_lifespan.R b/tests/testthat/test_cache_lifespan.R index 9b3f255..914122b 100644 --- a/tests/testthat/test_cache_lifespan.R +++ b/tests/testthat/test_cache_lifespan.R @@ -85,8 +85,9 @@ my_test_that("Cache is replaced if older than explicit lifespan", { # Explicit recreate argument trumps cache lifespan to determine recreation. my_test_that("Cache is replaced if recreate=TRUE even if cache is fresh", { expect_equal(0, countCacheItems()) - mySimpleCache("testDF", instruction={ buildTestFrame() }) fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") + expect_false(file_test("-f", fp)) + mySimpleCache("testDF", instruction={ buildTestFrame() }) expect_true(file_test("-f", fp)) expect_equal(1, countCacheItems()) t0 = file.info(fp)$ctime @@ -96,3 +97,32 @@ my_test_that("Cache is replaced if recreate=TRUE even if cache is fresh", { t1 = file.info(fp)$ctime expect_true(t1 > t0) }) + +my_test_that("simpleCache can pick up option specifying max cache age.", { + options(MAX.CACHE.AGE = 0) + fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") + expect_false(file_test("-f", fp)) + mySimpleCache("testDF", instruction={ buildTestFrame() }) + expect_true(file_test("-f", fp)) + t0 = file.info(fp)$ctime + Sys.sleep(1) # Time difference comparison reliability. + mySimpleCache("testDF", instruction={ buildTestFrame() }) + t1 = file.info(fp)$ctime + expect_true(t1 > t0) +}) + +my_test_that("Direct lifespan specification is preferred to background option", { + options(MAX.CACHE.AGE = 1) + fp = file.path(getOption("RCACHE.DIR"), "testDF.RData") + expect_false(file_test("-f", fp)) + mySimpleCache("testDF", instruction={ buildTestFrame() }) + expect_true(file_test("-f", fp)) + t0 = file.info(fp)$ctime + Sys.sleep(1) + mySimpleCache("testDF", instruction={ buildTestFrame() }) + expect_equal(t0, file.info(fp)$ctime) # Cache is fresh via MAX.CACHE.AGE. + Sys.sleep(1) # Time difference comparison reliability. + mySimpleCache("testDF", lifespan=0, instruction={ buildTestFrame() }) + t1 = file.info(fp)$ctime + expect_true(t1 > t0) # Cache is stale via lifespan. +})