Skip to content

Commit

Permalink
Merge pull request #499 from carpentries/use-child-files-for-db
Browse files Browse the repository at this point in the history
Account for child files in Rmd
  • Loading branch information
zkamvar authored Aug 31, 2023
2 parents e283e28 + fc6ba38 commit c205663
Show file tree
Hide file tree
Showing 13 changed files with 742 additions and 96 deletions.
13 changes: 12 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

## BUG FIX

* R Markdown documents with modificiations to child documents will now take into
account changes to the child documents (reported @jcolomb, #497; fixed
@zkamvar, #498).
* A broken test from the development version of {renv} fixed. This was a change
in output and not functionality, so there will be no user-visible changes
(reported: @zkamvar, #484; fixed: @zkamvar, #487).
Expand All @@ -21,6 +24,14 @@
* Tests for {renv} post 1.0.0 fixed so that they no longer run forever
interactively (reported: @zkamvar #500; fixed: @zkamvar, #501)

## MISC

* We are now testing against pandoc 2.19.2 in continuous integration.
* The discussion list link for the new lesson contributing template has been
fixed.
* examples have been modified to not use R Markdown lessons unless necessary,
reducing output and time needed to build the examples.

# sandpaper 0.12.4 (2023-06-16)

## BUG FIX
Expand Down Expand Up @@ -182,7 +193,7 @@
fixed: @zkamvar, #416 and
https://github.com/zkamvar/vise/commit/ee4798701a958ee48429980eb970266885f8265b

# MISC
## MISC

* @jcolomb has been added as a contributor in the DESCRIPTION.

Expand Down
71 changes: 69 additions & 2 deletions R/build_lesson.R
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,13 @@ build_lesson <- function(path = ".", rebuild = FALSE, quiet = !interactive(), pr
check_pandoc()
# 2. check if we are only building one file and get its slug to pass to the
# markdown and site functions.
slug <- if (fs::is_file(path)) get_slug(path) else NULL
slugpath <- get_build_slug(path)
slug <- slugpath$slug
# 3. set the source path global variable so that it can be used throughout the
# build process without explicitly needing to pass a variable from function
# to function, resetting the build path when the function exits (gracefully
# or ungracefully)
path <- set_source_path(path)
path <- slugpath$path
on.exit({
reset_build_paths()
})
Expand Down Expand Up @@ -101,3 +102,69 @@ build_lesson <- function(path = ".", rebuild = FALSE, quiet = !interactive(), pr

}

# Determine the build slug for lessons with child documents.
#
# The slug is the name of the file without the path or extension for the
# purposes of building a single file during the `serve()` and `knit` function
# operations.
#
# For child files, we need to take into account _where_ the child files exist.
#
# This function loops through the four possibilities of paths that can be passed
# to `build_lesson()`
#
# 1. a path to a lesson
# 2. the path to an existing source file
# 3. the path to a new source file
# 4. the path to a child file
#
# This function returns a list with the slug and the cleaned path to the lesson.
get_build_slug <- function(path) {
original_path <- path
not_file <- !fs::is_file(path)
# set the source path and return it
path <- set_source_path(path)

# CASE 1: path is a directory ---------------------------------------------
# The base case: if we are building a directory, we don't need a slug and
# we return early
if (not_file) {
return(list(slug = NULL, path = path))
}

# CASE 2: path is a source file -------------------------------------------
# get the resource list and make it one big vector (use the stored resource
# list to reduce lookup time)
sources <- unlist(.resources$get() %||% get_resource_list(path), use.names = FALSE)
# if we find the file in the sources, we can return the original path
if (all(fs::path_file(original_path) %in% fs::path_file(sources))) {
return(list(slug = get_slug(original_path), path = path))
}

# CASE 3: this is a new source file ---------------------------------------
# load the lesson object and find the children
children <- get_child_files(this_lesson(path))
if (length(children) == 0L) {
# no children anywhere so we return the slug of that file
return(list(slug = get_slug(original_path), path = path))
}

# CASE 4: we have a child file (maybe) ------------------------------------
# get the names of all possible parents
parents <- names(children)
# loop over the children and see if the child is part of the family
# this returns a single logical value that indicates _which parent_
# the child file belongs to
the_file <- vapply(children, function(possible, actual) {
any(fs::path_file(possible) == actual)
}, FUN.VALUE = logical(1),
actual = fs::path_file(original_path))
# select the parent file from the list
parent <- parents[the_file]
# if the parent does not exist, it's a new file that we somehow missed
parent <- if (length(parent) == 0L) original_path else parent
# if there are MULTIPLE parents, then just rebuild the whole thing (slug = NULL)
# otherwise return the slug
parent <- if (length(parent) > 1L) NULL else get_slug(parent)
return(list(slug = parent, path = path))
}
24 changes: 14 additions & 10 deletions R/build_markdown.R
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,7 @@ build_markdown <- function(path = ".", rebuild = FALSE, quiet = FALSE, slug = NU
outdir <- path_built(path)

# Determine build status for the episodes ------------------------------------
source_list <- .resources$get() %||% get_resource_list(path, warn = !quiet)
sources <- unlist(source_list, use.names = FALSE)
names(sources) <- get_slug(sources)
if (is.null(slug)) {
copy_maybe(sources[["config"]], fs::path(outdir, "config.yaml"))
copy_lockfile(sources, fs::path(outdir, "renv.lock"))
} else {
sources <- sources[slug]
}
sources <- get_build_sources(path, outdir, slug, quiet)

no_renv_needed <- !any(fs::path_ext(sources) %in% c("Rmd", "rmd"))

Expand Down Expand Up @@ -163,4 +155,16 @@ remove_rendered_html <- function(episodes) {
}



# Get a vector of markdown files to build with names.
get_build_sources <- function(path, outdir, slug = NULL, quiet) {
source_list <- .resources$get() %||% get_resource_list(path, warn = !quiet)
sources <- unlist(source_list, use.names = FALSE)
names(sources) <- get_slug(sources)
if (is.null(slug)) {
copy_maybe(sources[["config"]], fs::path(outdir, "config.yaml"))
copy_lockfile(sources, fs::path(outdir, "renv.lock"))
} else {
sources <- sources[slug]
}
return(sources)
}
11 changes: 10 additions & 1 deletion R/serve.R
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,16 @@
serve <- function(path = ".", quiet = !interactive(), ...) {
this_path <- root_path(path)
rend <- function(file_list = this_path) {
if (any(fs::is_file(file_list))) {
file_list <- file_list[endsWith(file_list, "md")]
if (length(file_list) == 0L) {
file_list <- this_path
}
}
for (f in file_list) {
if (!quiet) {
cli::cli_alert_info("Rebuilding {.path f}")
}
build_lesson(f, preview = FALSE, quiet = quiet)
}
}
Expand All @@ -86,7 +95,7 @@ serve <- function(path = ".", quiet = !interactive(), ...) {
no_git <- file.path(base, ".git")
# return a filter function for the files
function(x) {
x[!startsWith(x, no_site) | !startsWith(x, no_git)]
return(x[(!startsWith(x, no_site) | !startsWith(x, no_git))])
}
}
this_filter <- make_filter(this_path)
Expand Down
Loading

0 comments on commit c205663

Please sign in to comment.