diff --git a/NEWS.md b/NEWS.md index 5bf32c5a6d..1afe5ab1e4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -42,6 +42,8 @@ - `spin()` dropped support for `#-` as the chunk delimiter token. Please use `#+` or `# %%` or `#|` instead. +- Faster processing of cache dependencies in `dep_auto()` (thanks, @knokknok, #2318). + # CHANGES IN knitr VERSION 1.45 ## NEW FEATURES diff --git a/R/block.R b/R/block.R index dee9bdb8c9..cdc8a6a57b 100644 --- a/R/block.R +++ b/R/block.R @@ -345,7 +345,7 @@ eng_r = function(options) { objs, cache_globals(options$cache.globals, code), options$label, options$cache.path ) - dep_auto() + dep_auto(labels = options$label) } if (options$cache < 3) { if (options$cache.rebuild || !cache.exists) block_cache(options, res.orig, objs) diff --git a/R/cache.R b/R/cache.R index b45a619fe6..f5f3c63645 100644 --- a/R/cache.R +++ b/R/cache.R @@ -142,6 +142,8 @@ cache_rx = '_[abcdef0123456789]{32}[.](rdb|rdx|RData)$' #' is similar to the effect of the \code{dependson} option. It is supposed to be #' used in the first chunk of a document and this chunk must not be cached. #' @param path Path to the dependency file. +#' @param labels A vector of labels of chunks for which the dependencies will be +#' built. By default, dependencies for all chunks will be built. #' @return \code{NULL}. The dependencies are built as a side effect. #' @note Be cautious about \code{path}: because this function is used in a #' chunk, the working directory when the chunk is evaluated is the directory @@ -152,7 +154,7 @@ cache_rx = '_[abcdef0123456789]{32}[.](rdb|rdx|RData)$' #' @export #' @seealso \code{\link{dep_prev}} #' @references \url{https://yihui.org/knitr/demo/cache/} -dep_auto = function(path = opts_chunk$get('cache.path')) { +dep_auto = function(path = opts_chunk$get('cache.path'), labels = all_labels()) { # this function should be evaluated in the original working directory owd = setwd(opts_knit$get('output.dir')); on.exit(setwd(owd)) paths = valid_path(path, c('__objects', '__globals')) @@ -162,11 +164,10 @@ dep_auto = function(path = opts_chunk$get('cache.path')) { warning('corrupt dependency files? \ntry remove ', paste(paths, collapse = '; ')) return(invisible(NULL)) } - nms = intersect(names(knit_code$get()), names(locals)) # guarantee correct order - # locals may contain old chunk names; the intersection can be of length < 2 - if (length(nms) < 2) return(invisible(NULL)) - for (i in 2:length(nms)) { - if (length(g <- globals[[nms[i]]]) == 0) next + nms = intersect(all_labels(), names(locals)) # guarantee correct order + for (i in match(labels, nms)) { + # ignore first chunk (i < 2); locals may contain old chunk names (i will be NA) + if (is.na(i) || i < 2 || length(g <- globals[[nms[i]]]) == 0) next for (j in 1:(i - 1L)) { # check if current globals are in old locals if (any(g %in% locals[[nms[j]]])) diff --git a/man/dep_auto.Rd b/man/dep_auto.Rd index 00e18af6e1..5180a2bedc 100644 --- a/man/dep_auto.Rd +++ b/man/dep_auto.Rd @@ -4,10 +4,13 @@ \alias{dep_auto} \title{Build automatic dependencies among chunks} \usage{ -dep_auto(path = opts_chunk$get("cache.path")) +dep_auto(path = opts_chunk$get("cache.path"), labels = all_labels()) } \arguments{ \item{path}{Path to the dependency file.} + +\item{labels}{A vector of labels of chunks for which the dependencies will be +built. By default, dependencies for all chunks will be built.} } \value{ \code{NULL}. The dependencies are built as a side effect.