diff --git a/NEWS.md b/NEWS.md index 87eaa55d..81bbc7dd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,6 +12,9 @@ * `copyDependencyToDir()` no longer creates empty directories for dependencies that do not have any files. (@gadenbuie, #276) +* Closed #320: `copyDependencyToDir()` now works with dependencies +with specified attributes. (@dmurdoch, #321) + # htmltools 0.5.2 ## Breaking Changes diff --git a/R/html_dependency.R b/R/html_dependency.R index 662a323c..7b393ba8 100644 --- a/R/html_dependency.R +++ b/R/html_dependency.R @@ -354,9 +354,12 @@ copyDependencyToDir <- function(dependency, outputDir, mustWork = TRUE) { dir.create(target_dir) dependency$src$file <- normalizePath(target_dir, "/", TRUE) - files <- if (dependency$all_files) list.files(dir) else { - unlist(dependency[c('script', 'stylesheet', 'attachment')]) - } + if (dependency$all_files) + files <- list.files(dir) + else + files <- c(pluck_src(dependency$script), + pluck_src(dependency$stylesheet), + pluck_src(dependency$attachment)) if (length(files) == 0) { # This dependency doesn't include any files @@ -366,11 +369,12 @@ copyDependencyToDir <- function(dependency, outputDir, mustWork = TRUE) { } srcfiles <- file.path(dir, files) - if (any(!file.exists(srcfiles))) { + missing_srcfiles <- !file.exists(srcfiles) + if (any(missing_srcfiles)) { stop( sprintf( "Can't copy dependency files that don't exist: '%s'", - paste(srcfiles, collapse = "', '") + paste(srcfiles[missing_srcfiles], collapse = "', '") ) ) } diff --git a/R/utils.R b/R/utils.R index c72ae1f1..493e0afc 100644 --- a/R/utils.R +++ b/R/utils.R @@ -151,3 +151,12 @@ anyUnnamed <- function(x) { # List with name attribute; check for any "" any(!nzchar(nms)) } + +# Get the source filename out of a script or similar +# entry. +pluck_src <- function(x) { + if (is.character(x)) return(x) + if (is.list(x) && "src" %in% names(x)) return(x$src) + if (is.list(x)) return(vapply(x, pluck_src, "")) + NULL +} diff --git a/tests/testthat/test-deps.r b/tests/testthat/test-deps.r index eef577ce..b6337ef2 100644 --- a/tests/testthat/test-deps.r +++ b/tests/testthat/test-deps.r @@ -357,3 +357,90 @@ test_that("copyDependencyToDir() doesn't create an empty directory", { # to keep relativeTo() from throwing an error later in Rmd render process expect_match(copied_dep$src$file, normalizePath(tmp_rmd, "/", TRUE), fixed = TRUE) }) + +test_that("copyDependencyToDir() handles attributes", { + tmp_dep <- tempfile("dep") + dir.create(tmp_dep) + on.exit(unlink(tmp_dep)) + + tmp_txt <- "temp.txt" + path <- file.path(tmp_dep, tmp_txt) + writeLines("Some text in the text/plain dep", path) + + tmp_js <- "javascript.js" + path <- file.path(tmp_dep, tmp_js) + writeLines('console.log("log message");', path) + + tmp_rmd <- tempfile("rmd_files") + dir.create(tmp_rmd) + on.exit(unlink(tmp_rmd), add = TRUE) + + dep_with_attributes <- htmltools::htmlDependency( + name = "textPlain", + version = "9.9.9", + src = tmp_dep, + script = list(src = tmp_txt, type = "text/plain"), + all_files = FALSE + ) + + dep_without <- htmltools::htmlDependency( + name = "textPlain", + version = "9.9.9", + src = tmp_dep, + script = tmp_js, + all_files = FALSE + ) + + dep_with_both <- htmltools::htmlDependency( + name = "textPlain", + version = "9.9.9", + src = tmp_dep, + script = list(tmp_js, + list(src = tmp_txt, type = "text/plain")), + all_files = FALSE + ) + + dep_with_one_nested <- htmltools::htmlDependency( + name = "textPlain", + version = "9.9.9", + src = tmp_dep, + script = list(list(src = tmp_txt, type = "text/plain")), + all_files = FALSE + ) + + dep_with_missings <- htmltools::htmlDependency( + name = "textPlain", + version = "9.9.9", + src = tmp_dep, + script = list(tmp_js, + "foobar1", + list(src = "foobar2")), + all_files = FALSE + ) + + # None of these except the last should trigger errors as + # the first two did in issue #320 + + copyDependencyToDir(dep_with_attributes, tmp_rmd) + expect_equal(dir(tmp_rmd, recursive = TRUE), + "textPlain-9.9.9/temp.txt") + + unlink(dir(tmp_rmd, recursive = TRUE)) + copyDependencyToDir(dep_with_both, tmp_rmd) + expect_equal(dir(tmp_rmd, recursive = TRUE), + c("textPlain-9.9.9/javascript.js", + "textPlain-9.9.9/temp.txt")) + + unlink(dir(tmp_rmd, recursive = TRUE)) + copyDependencyToDir(dep_without, tmp_rmd) + expect_equal(dir(tmp_rmd, recursive = TRUE), + "textPlain-9.9.9/javascript.js") + + unlink(dir(tmp_rmd, recursive = TRUE)) + copyDependencyToDir(dep_with_one_nested, tmp_rmd) + expect_equal(dir(tmp_rmd, recursive = TRUE), + "textPlain-9.9.9/temp.txt") + + expect_error(copyDependencyToDir(dep_with_missings, tmp_rmd)) + +})