Skip to content

Commit ceff743

Browse files
authored
Merge pull request #140 from carpentries/no-bad-children-fix-139
do not error if child document cannot be processed
2 parents 3fef1aa + 0a02282 commit ceff743

5 files changed

Lines changed: 137 additions & 2 deletions

File tree

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: pegboard
22
Title: Explore and Manipulate Markdown Curricula from the Carpentries
3-
Version: 0.7.0
3+
Version: 0.7.1
44
Authors@R: c(
55
person(given = "Zhian N.",
66
family = "Kamvar",

NEWS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# pegboard 0.7.1 (2023-10-03)
2+
3+
* child chunk options that would fail out of context no longer cause a failure.
4+
(reported: @trhallam, https://github.com/carpentries/workbench/issues/74,
5+
#139; fixed: @zkamvar, #140)
6+
17
# pegboard 0.7.0 (2023-10-02)
28

39
This release introduces automated processing of {knitr} child files, which

R/find_children.R

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,20 @@ child_file_from_code_blocks <- function(nodes) {
164164
use_children <- xml2::xml_has_attr(nodes, "child")
165165
if (any(use_children)) {
166166
nodes <- nodes[use_children]
167-
res <- gsub("[\"']", "", xml2::xml_attr(nodes, "child"))
167+
children <- xml2::xml_attr(nodes, "child")
168+
res <- vector(length = length(children), mode = "list")
169+
for (child in seq_along(children)) {
170+
res[[child]] <- eval(tryCatch({
171+
eval(parse(text = children[child]))
172+
},
173+
error = function(e) {
174+
msg <- "could not process child document {children[child]}"
175+
pb_message(glue::glue(msg))
176+
return(NULL)
177+
}
178+
))
179+
}
180+
res <- unlist(res[lengths(res) > 0L], use.names = FALSE)
168181
} else {
169182
character(0)
170183
}
@@ -277,6 +290,10 @@ read_children <- function(parent, all_children = list(), ...) {
277290
known_children <- names(all_children)
278291
new_child <- !child %in% known_children
279292
if (new_child) {
293+
is_valid <- validate_child(child, parent)
294+
if (!is_valid) {
295+
next
296+
}
280297
# read in the new child with a parent listed
281298
this_child <- Episode$new(child, parent = list(parent), ...)
282299
} else {
@@ -332,3 +349,14 @@ add_parent <- function(child, parent) {
332349
return(invisible(NULL))
333350
}
334351

352+
validate_child <- function(child, parent) {
353+
if (fs::file_exists(child)) {
354+
return(TRUE)
355+
}
356+
parent$children <- parent$children[parent$children != child]
357+
child_name <- sQuote(fs::path_rel(child, parent$lesson), q = 2)
358+
parent_name <- fs::path_rel(parent$path, parent$lesson)
359+
msg <- "could not process child document {child_name} (in {parent_name})"
360+
pb_message(glue::glue(msg))
361+
return(FALSE)
362+
}

tests/testthat/_snaps/find_children.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,55 @@
5050
learners/setup.md:26 [needs HTTPS]: [Terminal.app](http://example.com/terminal)
5151
episodes/files/child.md:2 [missing file (relative to episodes/)]: [broken link](this-file-does-not-exist.md)
5252

53+
# missing children will not be read [plain]
54+
55+
Code
56+
lnk <- lsn$validate_links()
57+
Message <cliMessage>
58+
! There were errors in 3/4 links
59+
( ) Links must use HTTPS <https://https.cio.gov/everything/>
60+
( ) Some linked internal files do not exist <https://carpentries.github.io/sandpaper/articles/include-child-documents.html#workspace-consideration>
61+
62+
learners/setup.md:18 [needs HTTPS]: [the PuTTY terminal](http://example.com/putty)
63+
learners/setup.md:26 [needs HTTPS]: [Terminal.app](http://example.com/terminal)
64+
episodes/files/child.md:2 [missing file (relative to episodes/)]: [broken link](this-file-does-not-exist.md)
65+
66+
# missing children will not be read [ansi]
67+
68+
Code
69+
lnk <- lsn$validate_links()
70+
Message <cliMessage>
71+
! There were errors in 3/4 links
72+
( ) Links must use HTTPS <https://https.cio.gov/everything/>
73+
( ) Some linked internal files do not exist <https://carpentries.github.io/sandpaper/articles/include-child-documents.html#workspace-consideration>
74+
75+
learners/setup.md:18 [needs HTTPS]: [the PuTTY terminal](http://example.com/putty)
76+
learners/setup.md:26 [needs HTTPS]: [Terminal.app](http://example.com/terminal)
77+
episodes/files/child.md:2 [missing file (relative to episodes/)]: [broken link](this-file-does-not-exist.md)
78+
79+
# missing children will not be read [unicode]
80+
81+
Code
82+
lnk <- lsn$validate_links()
83+
Message <cliMessage>
84+
! There were errors in 3/4 links
85+
◌ Links must use HTTPS <https://https.cio.gov/everything/>
86+
◌ Some linked internal files do not exist <https://carpentries.github.io/sandpaper/articles/include-child-documents.html#workspace-consideration>
87+
88+
learners/setup.md:18 [needs HTTPS]: [the PuTTY terminal](http://example.com/putty)
89+
learners/setup.md:26 [needs HTTPS]: [Terminal.app](http://example.com/terminal)
90+
episodes/files/child.md:2 [missing file (relative to episodes/)]: [broken link](this-file-does-not-exist.md)
91+
92+
# missing children will not be read [fancy]
93+
94+
Code
95+
lnk <- lsn$validate_links()
96+
Message <cliMessage>
97+
! There were errors in 3/4 links
98+
◌ Links must use HTTPS <https://https.cio.gov/everything/>
99+
◌ Some linked internal files do not exist <https://carpentries.github.io/sandpaper/articles/include-child-documents.html#workspace-consideration>
100+
101+
learners/setup.md:18 [needs HTTPS]: [the PuTTY terminal](http://example.com/putty)
102+
learners/setup.md:26 [needs HTTPS]: [Terminal.app](http://example.com/terminal)
103+
episodes/files/child.md:2 [missing file (relative to episodes/)]: [broken link](this-file-does-not-exist.md)
104+

tests/testthat/test-find_children.R

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,52 @@ cli::test_that_cli("children are validated along with parents", {
110110
expect_equal(lnk$enforce_https, c(FALSE, FALSE, TRUE, TRUE))
111111
})
112112

113+
cli::test_that_cli("missing children will not be read", {
114+
# setup -------------------------------------------------------------------
115+
tmp <- withr::local_tempdir()
116+
test_dir <- fs::path(tmp, "sandpaper-fragment")
117+
fs::dir_copy(lesson_fragment("sandpaper-fragment"), test_dir)
118+
fs::dir_copy(
119+
test_path("examples", "child-example", "files"),
120+
fs::path(test_dir, "episodes")
121+
)
122+
# create two files in the lesson with the same children -------------------
123+
parent_file <- fs::path(test_dir, "episodes", "intro.Rmd")
124+
second_parent_file <- fs::path(test_dir, "episodes", "next.Rmd")
125+
fs::file_copy(
126+
test_path("examples", "child-example", "parent.Rmd"),
127+
parent_file,
128+
overwrite = TRUE
129+
)
130+
fs::file_copy(
131+
test_path("examples", "child-example", "parent.Rmd"),
132+
second_parent_file,
133+
overwrite = TRUE
134+
)
135+
cat("```{r child=file.path(snippets, \"test.Rmd\")}\n```\n",
136+
file = parent_file,
137+
append = TRUE
138+
)
139+
# set the order in the config --------------------------------------------
140+
cfg <- readLines(fs::path(test_dir, "config.yaml"))
141+
eplist <- which(endsWith(cfg, "intro.Rmd"))
142+
cfg[eplist] <- paste0(cfg[eplist], "\n - next.Rmd")
143+
writeLines(cfg, fs::path(test_dir, "config.yaml"))
144+
children_names <- fs::path(
145+
test_dir, "episodes", "files",
146+
c("child.md", "child-2.Rmd", "child-3.md")
147+
)
148+
149+
expect_message(lsn <- Lesson$new(test_dir, jekyll = FALSE),
150+
"could not process child document file.path(snippets, \"test.Rmd\")",
151+
fixed = TRUE
152+
)
153+
154+
expect_snapshot(lnk <- lsn$validate_links())
155+
expect_s3_class(lnk, "data.frame")
156+
expect_paths <- c("learners/setup.md", "learners/setup.md", "episodes/files/child.md", "episodes/files/child-3.md")
157+
expect_equal(lnk$filepath, fs::path(expect_paths))
158+
expect_equal(lnk$internal_file, c(TRUE, TRUE, FALSE, TRUE))
159+
expect_equal(lnk$enforce_https, c(FALSE, FALSE, TRUE, TRUE))
160+
})
161+

0 commit comments

Comments
 (0)