Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ Suggests:
knitr,
testthat (>= 3.0.0),
readr,
withr (>= 2.5.0)
withr (>= 2.5.0),
purrr
Config/testthat/edition: 3
VignetteBuilder:
knitr
35 changes: 29 additions & 6 deletions R/fileSummary.R
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#' Summarize revision and QC history for a file
#' Summarize revision and QC history for a file or directory
#'
#' @description
#' Generates a comprehensive summary of the revision and quality control (QC) history
Expand All @@ -8,12 +8,14 @@
#' * Historical information about previous authors
#' * Historical information about previous QC reviewers
#'
#' @param .file File path.
#' @param .file File or directory path.
#'
#' @details
#' The function prints a formatted summary to the console and invisibly returns
#' the data for programmatic use. Non-existent files generate warnings and are
#' skipped. Files not found in the repository history are also skipped.
#' the data for programmatic use. If a directory is supplied, each immediate
#' file in that directory is summarized and a named list of results is returned.
#' Non-existent files generate warnings and are skipped. Files not found in the
#' repository history are also skipped.
#'
#' QC status can be:
#' * "QC up to date" - Latest revision has been QC'd
Expand All @@ -26,19 +28,34 @@
#' fileSummary("script/data-assembly/study-101.R")
#'
#' # Process all files in a directory
#' purrr::walk(list.files("script/data-assembly", full.names = TRUE), ~ fileSummary(.file = .x))
#' fileSummary("script/data-assembly")
#' }
#'
#' @export
fileSummary <- function(.file) {
if (length(.file) != 1) {
stop("'.file' must be a single file path")
stop("'.file' must be a single file or directory path")
}

if (!file.exists(.file)) {
warning(paste0(.file, " does not exist"))
return(invisible(NULL))
}

if (fs::is_dir(.file)) {
files <- list.files(.file, full.names = TRUE)
files <- files[!fs::is_dir(files)]

if (length(files) == 0) {
warning(paste0(.file, " contains no files"))
return(invisible(list()))
}

out <- lapply(files, fileSummary_one)
names(out) <- files

return(invisible(out))
}

log_df <- tryCatch(
svnCommand(.file = .file, .command = "log"),
Expand Down Expand Up @@ -152,3 +169,9 @@ fileSummary <- function(.file) {

return(invisible(out))
}

#' Internal helper for per-file summaries.
#' @noRd
fileSummary_one <- function(.file) {
fileSummary(.file = .file)
}
12 changes: 7 additions & 5 deletions man/fileSummary.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 37 additions & 2 deletions tests/testthat/test-fileSummary.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,44 @@ create_test_svn()
logAccept("script/data-assembly/da-functions.R")
logAssign("script/model-summary.Rmd")

test_that("Function requires single file input", {
test_that("Function requires single file or directory input", {
da_files <- c(
"script/data-assembly/da-functions.R",
"script/data-assembly/da-study-abc.Rmd"
)
expect_error(fileSummary(da_files), "must be a single file or directory path")
})

test_that("Works correctly for a directory input", {
da_directory <- fileSummary("script/data-assembly")
da_files <- list.files("script/data-assembly", full.names = TRUE)
expect_error(fileSummary(da_files), "must be a single file path")
da_files <- da_files[!fs::is_dir(da_files)]

expect_true(is.list(da_directory))
expect_setequal(names(da_directory), da_files)
expect_true(all(vapply(da_directory, is.list, logical(1))))
})

test_that("Directory input matches purrr::walk-based file summaries", {
testthat::skip_if_not_installed("purrr")

da_files <- list.files("script/data-assembly", full.names = TRUE)
da_files <- da_files[!fs::is_dir(da_files)]

from_directory <- fileSummary("script/data-assembly")

from_walk <- list()
purrr::walk(
da_files,
~ {
from_walk[[.x]] <<- fileSummary(.file = .x)
}
)

from_directory <- from_directory[order(names(from_directory))]
from_walk <- from_walk[order(names(from_walk))]

expect_equal(from_directory, from_walk)
})

test_that("Works correctly for a single file QC filed", {
Expand Down