diff --git a/DESCRIPTION b/DESCRIPTION index 928867b..7e51934 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: ghqc Title: Manage QC via GitHub Issues using Shiny Apps -Version: 0.3.3 +Version: 0.3.4 Authors@R: c( person("Anne", "Zheng", email = "anne@a2-ai.com", role = c("aut")), person("Jenna", "Johnson", email = "jenna@a2-ai.com", role = c("aut")), diff --git a/NEWS.md b/NEWS.md index bcb26df..aaffc9f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,7 @@ +# ghqc 0.3.4 + +- adds warning to checklist validation if checklist yamls lack a trailing newline + # ghqc 0.3.3 - refactors `setup_ghqc()` such that each interactive input is (y/N) diff --git a/R/checklist_validation.R b/R/checklist_validation.R index 11a80d4..b52c518 100644 --- a/R/checklist_validation.R +++ b/R/checklist_validation.R @@ -5,19 +5,27 @@ validate_checklists <- function(config_path = ghqc_config_path()) { lapply(checklist_ls, function(x) val_checklist(x)) } +checklist_has_trailing_newline <- function(file) { + content <- readChar(file, file.info(file)$size, useBytes = TRUE) + if (nchar(content) == 0) return(FALSE) # empty file + return(substr(content, nchar(content), nchar(content)) == "\n") +} + #' @importFrom yaml yaml.load_file val_checklist <- function(checklist) { content <- tryCatch({ - yaml::yaml.load_file(checklist) - }, error = function(e) { + yaml::yaml.load_file(checklist, readLines.warn = FALSE) + }, + error = function(e) { NULL }) if (is.null(content)) return(list(valid = FALSE, reason = "File is not a valid yaml format")) - if (length(content) == 0) return(list(valid = FALSE, reason = "File is blank")) #CASE 1: emply file + if (length(content) == 0) return(list(valid = FALSE, reason = "File is blank")) #CASE 1: empty file if (length(content) != 1) return(list(valid = FALSE, reason = "There are too many top level elements. The only top level should be the checklist title")) # CASE 2: Multiple top levels that create multiple lists when reading in the yaml if (!inherits(content, "list")) return(list(valid = FALSE, reason = "Only strings found. Use ':' for headers and '-' for checklist items")) # CASE 3: only a single. No top levels or elements if (any(sapply(content[[1]], function(x) class(x) != "character"))) return(list(valid = FALSE, reason = "There are too many sublevels. Checklist only supports a title and one section level")) + if (!checklist_has_trailing_newline(checklist)) return(list(valid = TRUE, reason = "File does not have a trailing newline")) # checklist is valid, but give a warning list(valid = TRUE, reason = NA) } @@ -40,6 +48,7 @@ invalid_checklist_rename <- function(checklist, check_structure) { #' @importFrom cli cli_alert_info print_checklists <- function(config_path) { res <- validate_checklists(config_path = config_path) + print_check <- as.data.frame(sapply(names(res), function(x) { elem <- gsub("INVALID - ", "", basename(x)) bullet <- "v" @@ -47,6 +56,10 @@ print_checklists <- function(config_path) { elem <- c(elem, res[[x]]$reason) bullet <- c("x", " ") } + else if (res[[x]]$valid && !is.na(res[[x]]$reason)) { + elem <- c(elem, res[[x]]$reason) + bullet <- c("!", " ") + } list(elem = elem, bullet = bullet) })) checks <- unlist(print_check["elem", ])