From 26b36c86c6a4cf7ddd87159ae2bcfd5f80e0fb51 Mon Sep 17 00:00:00 2001 From: jenna-a2ai Date: Mon, 18 Nov 2024 20:24:47 +0000 Subject: [PATCH 01/15] checklist name var --- R/app_01_assign.R | 1 + R/app_01_assign_utils.R | 2 +- R/app_02_resolve.R | 1 + R/app_03_record.R | 1 + R/custom_options.R | 45 +++++++++++++++++++++++++++++++++++++++++ R/info_repo.R | 2 ++ 6 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 R/custom_options.R diff --git a/R/app_01_assign.R b/R/app_01_assign.R index 985205c..1dd50ef 100644 --- a/R/app_01_assign.R +++ b/R/app_01_assign.R @@ -10,6 +10,7 @@ #' @export ghqc_assign_app <- function() { if (!exists("info_repo_path", .le)) ghqc_set_info_repo() + get_custom_options() # error handling before starting app root_dir <- rproj_root_dir() diff --git a/R/app_01_assign_utils.R b/R/app_01_assign_utils.R index 8b4019c..1544f88 100644 --- a/R/app_01_assign_utils.R +++ b/R/app_01_assign_utils.R @@ -308,7 +308,7 @@ create_checklist_preview_event <- function(input, iv, ns, name, checklists) { footer = NULL, easyClose = TRUE, renderUI({ - "Select a checklist to preview in the Checklist dropdown." + glue::glue("Select a {get_checklist_display_name_var()} to preview in the {get_checklist_display_name_var(capitalized = TRUE)} dropdown.") }) ) ) diff --git a/R/app_02_resolve.R b/R/app_02_resolve.R index 8086feb..223d12e 100644 --- a/R/app_02_resolve.R +++ b/R/app_02_resolve.R @@ -13,6 +13,7 @@ #' @export ghqc_resolve_app <- function() { if (!exists("info_repo_path", .le)) ghqc_set_info_repo() + get_custom_options() # error handling before starting app remote <- check_github_credentials() diff --git a/R/app_03_record.R b/R/app_03_record.R index 7f3a7f2..8b8586a 100644 --- a/R/app_03_record.R +++ b/R/app_03_record.R @@ -8,6 +8,7 @@ #' @export ghqc_record_app <- function() { if (!exists("info_repo_path", .le)) ghqc_set_info_repo() + get_custom_options() # error handling before starting app remote <- check_github_credentials() diff --git a/R/custom_options.R b/R/custom_options.R new file mode 100644 index 0000000..790b6ae --- /dev/null +++ b/R/custom_options.R @@ -0,0 +1,45 @@ +get_checklist_display_name_var <- function(capitalized = FALSE, plural = FALSE) { + #browser() + checklist_display_name_var <- .le$checklist_display_name_var + + if (is.null(checklist_display_name_var)) { + checklist_display_name_var <- "checklist" + } + + if (plural) { + checklist_display_name_var <- pluralize(checklist_display_name_var) + } + + if (capitalized) { + checklist_display_name_var <- capitalize(checklist_display_name_var) + } + + return(checklist_display_name_var) +} + +# get_dne_var <- function(capitalized = FALSE) { +# dne_var <- .le$dne_var +# +# } + + +get_custom_options <- function() { + custom_options_yaml <- file.path(.le$info_repo_path, "custom_options.yaml") + custom_options <- yaml::read_yaml(custom_options_yaml) + custom_options + + lapply(names(custom_options), function(option_key) { + option_value <- custom_options[[option_key]] + assign(option_key, option_value, envir = .le) + }) +} + +capitalize <- function(word) { + first_letter <- toupper(substring(word, 1, 1)) + rest_of_word <- substring(word, 2) + glue::glue("{first_letter}{rest_of_word}") +} + +pluralize <- function(word) { + glue::glue("{word}s") +} diff --git a/R/info_repo.R b/R/info_repo.R index 68a403d..0e64fcc 100644 --- a/R/info_repo.R +++ b/R/info_repo.R @@ -38,3 +38,5 @@ info_repo_not_found <- function() { error(.le$logger, "GHQC_INFO_REPO not found. Please set in ~/.Renviron") rlang::abort(message = "GHQC_INFO_REPO not found. Please set in ~/.Renviron") } + + From dccb3e30c64d7e7dc644ffb37ce1afb11ad70a94 Mon Sep 17 00:00:00 2001 From: jenna-a2ai Date: Mon, 18 Nov 2024 21:42:32 +0000 Subject: [PATCH 02/15] checklist var name --- R/app_01_assign_server.R | 12 ++++++------ R/app_01_assign_utils.R | 8 ++++---- R/app_03_record_server.R | 3 ++- R/app_03_record_utils.R | 6 +++--- R/create_yaml.R | 2 +- R/multi_issue.R | 6 +++--- R/pre_app_errors.R | 2 +- R/validation.R | 2 +- R/validation_errors.R | 8 -------- 9 files changed, 21 insertions(+), 28 deletions(-) diff --git a/R/app_01_assign_server.R b/R/app_01_assign_server.R index a11b940..2883981 100644 --- a/R/app_01_assign_server.R +++ b/R/app_01_assign_server.R @@ -205,7 +205,7 @@ return "
" + escape(item.username) + "
" div( style = "display: flex; justify-content: flex-end; padding-bottom: 20px;", actionButton(ns("file_info"), - label = HTML("Preview all available checklists"), + label = HTML(glue::glue("Preview all available {get_checklist_display_name_var(plural = TRUE)}")), class = "preview-button", style = "min-width: auto; display: inline-block; text-align: center; line-height: 2em; height: 2em;" ) #actionButton @@ -354,7 +354,7 @@ return "
" + escape(item.username) + "
" } success_note <- { if (custom_checklist_selected()) { - HTML("Issue(s) created successfully.
Remember to manually edit Custom QC checklists on GitHub.") + HTML(glue::glue("Issue(s) created successfully.
Remember to manually edit Custom {get_checklist_display_name_var(plural = TRUE)} on GitHub.")) } else { "Issue(s) created successfully." @@ -382,7 +382,7 @@ return "
" + escape(item.username) + "
" title = tags$div(modalButton("Dismiss"), style = "text-align: right;"), footer = NULL, easyClose = TRUE, - "Each file input will require a checklist type. Each checklist type will have its own items associated with it.", + glue::glue("Each selected file will require a {get_checklist_display_name_var()} type. Each {get_checklist_display_name_var()} type will have its own items associated with it."), "See below for a reference of all types and their items.", br(), br(), @@ -402,7 +402,7 @@ return "
" + escape(item.username) + "
" title = tags$div(modalButton("Dismiss"), style = "text-align: right;"), footer = NULL, easyClose = TRUE, - "Each file input will require a checklist type. Each checklist type will have its own items associated with it.", + glue::glue("Each selected file will require a {get_checklist_display_name_var()} type. Each {get_checklist_display_name_var()} type will have its own items associated with it."), "See below for a reference of all types and their items.", br(), br(), @@ -416,12 +416,12 @@ return "
" + escape(item.username) + "
" output$file_info_panel <- renderUI({ req(checklists) req(input$checklist_info) - debug(.le$logger, glue::glue("Checklist selected for review: {input$checklist_info}")) + debug(.le$logger, glue::glue("{get_checklist_display_name_var(capitalized = TRUE)} selected for review: {input$checklist_info}")) info <- checklists[[input$checklist_info]] log_string <- glue::glue_collapse(info, sep = "\n") - debug(.le$logger, glue::glue("Items found in the checklist: \n{log_string}")) + debug(.le$logger, glue::glue("Items found in the {get_checklist_display_name_var()}: \n{log_string}")) list <- convert_list_to_ui(info) # checklists needs additional formatting for list of named elements diff --git a/R/app_01_assign_utils.R b/R/app_01_assign_utils.R index 1544f88..ec70069 100644 --- a/R/app_01_assign_utils.R +++ b/R/app_01_assign_utils.R @@ -60,7 +60,7 @@ render_selected_list <- function(input, ns, iv, items = NULL, checklist_choices choices = c("", checklist_choices), #select checklist (required) width = "100%", selected = NULL, # Ensures no default selection - options = list(placeholder = "Checklist") + options = list(placeholder = get_checklist_display_name_var(capitalized = TRUE)) ) button_input <- actionButton( @@ -73,7 +73,7 @@ render_selected_list <- function(input, ns, iv, items = NULL, checklist_choices preview_input <- actionButton( ns(preview_input_id), - label = HTML("Preview
checklist
"), + label = HTML(glue::glue("Preview
{get_checklist_display_name_var()}
")), style = "height: 34px !important; font-size: 12px !important; padding: 2px 2px 2px 2px !important; color: #5f5f5f !important; line-height: 1.2em", #style = "min-width: auto; display: inline-block; text-align: center; line-height: 2em; height: 2em;", #class = "checklist-preview-button" @@ -226,8 +226,8 @@ convert_list_to_ui <- function(checklists, parent_name = NULL, is_first = TRUE) first_child <- FALSE } } else { - error(.le$logger, glue::glue("Checklist not supported: {checklists}")) - rlang::abort("Unsupported type of checklist") + error(.le$logger, glue::glue("{get_checklist_display_name_var(capitalized = TRUE)} not supported: {checklists}")) + rlang::abort(glue::glue("Unsupported type of {get_checklist_display_name_var()}")) } debug(.le$logger, "Converted list to UI successfully") return(ui_elements) diff --git a/R/app_03_record_server.R b/R/app_03_record_server.R index bcc2487..af216fc 100644 --- a/R/app_03_record_server.R +++ b/R/app_03_record_server.R @@ -118,7 +118,8 @@ ghqc_record_server <- function(id, remote, org, repo, all_milestones) { actionButton(ns("return"), "Return"), style = "text-align: right;" ), - HTML(paste("It is recommended that relevant GitHub Issues and Milestones are closed upon completion of QC, and checklists within GitHub Issues are checked to indicate QCed items.

You may want to double check the following items for outstanding QC progress:

", modal_check()$message)), + #HTML(paste(glue::glue("It is recommended that all relevant GitHub Issues and Milestones are closed and all {get_checklist_display_name_var()} items within GitHub Issues are checked off to indicate completion of QC.

You may want to double check the following items for outstanding QC progress:

"), modal_check()$message)), + HTML(paste(glue::glue("Upon completion of QC, It is recommended that:
- All selected Milestones are closed
- All Issues within selected Milestones are closed
- All {get_checklist_display_name_var()} items within relevant Issues are completed

You may want to review the following items on GitHub for outstanding QC progress:

"), modal_check()$message)), tags$style(HTML(" .modal-content { word-wrap: break-word; /* Allows long text to break into new lines */ diff --git a/R/app_03_record_utils.R b/R/app_03_record_utils.R index 550100e..aae85cf 100644 --- a/R/app_03_record_utils.R +++ b/R/app_03_record_utils.R @@ -55,8 +55,8 @@ generate_open_issue_message <- function(open_issues, warning_icon_html) { generate_open_checklist_message <- function(issues_with_open_checklists, warning_icon_html) { messages <- c() if (length(issues_with_open_checklists) > 0) { - messages <- c(messages, sprintf( - "%s The selected Milestones contain the following Issues with open checklist items:
    %s

", + messages <- c(messages, sprintf(glue::glue( + "%s The selected Milestones contain the following Issues with open {get_checklist_display_name_var()} items:
    %s

"), warning_icon_html, generate_tiered_html_list_with_hyperlink(issues_with_open_checklists) )) } @@ -79,7 +79,7 @@ determine_modal_message_report <- function(owner, repo, milestone_names) { log_string <- glue::glue("Modal Check Inputs: - Open Milestones: {glue::glue_collapse(open_milestones, sep = ', ')} - Open Issues: {glue::glue_collapse(open_issues, sep = ', ')} - - Issues with unchecked checklist items: {glue::glue_collapse(open_checklists, sep = ', ')} + - Issues with unchecked {get_checklist_display_name_var()} items: {glue::glue_collapse(open_checklists, sep = ', ')} ") log4r::debug(.le$logger, log_string) diff --git a/R/create_yaml.R b/R/create_yaml.R index 26351b2..4ea4138 100644 --- a/R/create_yaml.R +++ b/R/create_yaml.R @@ -11,7 +11,7 @@ get_checklists <- function() { basename(invalid_checklist) %>% stringr::str_remove("\\.ya?ml$") %>% stringr::str_remove("INVALID - ") }) invalid_checklist_names_col <- glue::glue_collapse(invalid_checklist_names, sep = ", ", last = " and ") - warn(.le$logger, glue::glue("The following checklist(s) are invalid and will therefore not be selectable in the app: {invalid_checklist_names_col}. Run check_ghqc_configuration() for guidance.")) + warn(.le$logger, glue::glue("The following {get_checklist_display_name_var()}(s) are invalid and will therefore not be selectable in the app: {invalid_checklist_names_col}. Run check_ghqc_configuration() for guidance.")) # remove bad checklists yaml_checklists <- yaml_checklists[!invalid_search] diff --git a/R/multi_issue.R b/R/multi_issue.R index a6d5827..1797173 100644 --- a/R/multi_issue.R +++ b/R/multi_issue.R @@ -62,12 +62,12 @@ create_issues <- function(data) { file_names <- glue::glue_collapse(purrr::map(data$files, "name"), sep = ", ", last = " and ") - debug(.le$logger, glue::glue("Creating checklists for files: {file_names}")) + debug(.le$logger, glue::glue("Creating {get_checklist_display_name_var(plural = TRUE)} for files: {file_names}")) # create an issue for each file lapply(data$files, function(file) { issue <- create_issue(file, issue_params) - debug(.le$logger, glue::glue("Created checklist for file: {file$name}")) + debug(.le$logger, glue::glue("Created {get_checklist_display_name_var()} for file: {file$name}")) if (!is.null(data$milestone)) { debug(.le$logger, glue::glue("Milestone: {data$milestone}")) } @@ -77,7 +77,7 @@ create_issues <- function(data) { debug(.le$logger, glue::glue("Issue number: {issue$number}")) return(issue) }) - info(.le$logger, glue::glue("Created checklist(s) for file(s): {file_names}")) + info(.le$logger, glue::glue("Created {get_checklist_display_name_var()}(s) for file(s): {file_names}")) } # create_issues #' @importFrom gh gh diff --git a/R/pre_app_errors.R b/R/pre_app_errors.R index 4c47d97..a23f122 100644 --- a/R/pre_app_errors.R +++ b/R/pre_app_errors.R @@ -18,7 +18,7 @@ get_valid_checklists <- function() { yaml_checklists <- get_checklists() }, error = function(e) { - error(.le$logger, glue::glue("There was an error retrieving checklists: {e$message}")) + error(.le$logger, glue::glue("There was an error retrieving {get_checklist_display_name_var(plural = TRUE)}: {e$message}")) rlang::abort(e$message) } ) diff --git a/R/validation.R b/R/validation.R index 61493fa..a052342 100644 --- a/R/validation.R +++ b/R/validation.R @@ -55,7 +55,7 @@ validate_description <- function(description) { } # validate description validate_checklist_type <- function(checklist_type, file_name) { - #err_if_invalid_checklist_type(checklist_type, file_name) + } validate_items <- function(items) { diff --git a/R/validation_errors.R b/R/validation_errors.R index da26183..484b501 100644 --- a/R/validation_errors.R +++ b/R/validation_errors.R @@ -86,13 +86,5 @@ err_if_not_list_of_lists <- function(files) { } } -err_if_invalid_checklist_type <- function(checklist_type, file_name) { - valid_checklist_types <- c("R", "mod", "cpp", "vpc") - if (!checklist_type %in% valid_checklist_types) { - rlang::abort(message = glue::glue("{checklist_type} not a valid checklist type for file {file_name}"), - class = "input_error", - x = checklist_type) - } -} From ef9c7e9d0def03bc4ecfb21996c277205799582b Mon Sep 17 00:00:00 2001 From: jenna-a2ai Date: Mon, 18 Nov 2024 21:54:43 +0000 Subject: [PATCH 03/15] prepended_checklist_note --- R/custom_options.R | 16 ++++++++++++++++ R/format.R | 19 +------------------ 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/R/custom_options.R b/R/custom_options.R index 790b6ae..f3f1797 100644 --- a/R/custom_options.R +++ b/R/custom_options.R @@ -17,6 +17,22 @@ get_checklist_display_name_var <- function(capitalized = FALSE, plural = FALSE) return(checklist_display_name_var) } +get_prepended_checklist_note <- function() { + prepended_checklist_note <- .le$prepended_checklist_note + + # if not given, make the empty string + if (is.null(prepended_checklist_note)) { + prepended_checklist_note <- "" + } + + # if given, append with a newline + else { + prepended_checklist_note <- paste0(prepended_checklist_note, "\n") + } + + return(prepended_checklist_note) +} + # get_dne_var <- function(capitalized = FALSE) { # dne_var <- .le$dne_var # diff --git a/R/format.R b/R/format.R index 9cab38d..40801e6 100644 --- a/R/format.R +++ b/R/format.R @@ -4,7 +4,7 @@ format_issue_body <- function(checklist_type, file_path) { file_items <- checklists[[checklist_type]] qc_checklist <- format_checklist_items(file_items) metadata <- format_metadata(checklist_type, file_path) - note <- format_note() + note <- get_prepended_checklist_note() issue_body_content <- format_body_content(metadata = metadata, checklist_type = checklist_type, @@ -180,23 +180,6 @@ get_file_contents_url <- function(file_path, git_sha) { file.path(https_url, "blob", substr(git_sha, 1, 6), file_path) } -format_note <- function() { - note <- { - if (file.exists(file.path(.le$info_repo_path, "note"))) { - custom_note <- readr::read_file(file.path(.le$info_repo_path, "note")) - if (stringr::str_sub(custom_note, start =-2) != "\n") { - custom_note <- paste0(custom_note,"\n") - } - custom_note - } - else { - "" - } - } - - return(note) -} - format_body_content <- function(metadata, checklist_type, note, qc_checklist) { glue::glue("## Metadata\n\n {metadata}\n\n From b0c3dd3028a9ea113877cc3e5f5e0d414c457107 Mon Sep 17 00:00:00 2001 From: jenna-a2ai Date: Tue, 19 Nov 2024 15:42:48 +0000 Subject: [PATCH 04/15] ui fixed --- inst/css/styles.css | 4 +++- inst/js/adjust_grid.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/inst/css/styles.css b/inst/css/styles.css index 9c3849f..c738ad0 100644 --- a/inst/css/styles.css +++ b/inst/css/styles.css @@ -140,8 +140,10 @@ div[id$="-main_container"] { .grid-items { display: grid; column-gap: 10px; - grid-template-columns: 67px minmax(100px, 1fr) minmax(125px, 1fr) 50px; /*minmax(100px, auto) */ + grid-template-columns: 67px minmax(100px, 1fr) minmax(125px, 1fr) minmax(50px, auto); /*minmax(100px, auto) */ margin-bottom: 15px; + width: 100%; + transition: 0.5s; } /* diff --git a/inst/js/adjust_grid.js b/inst/js/adjust_grid.js index 31c5375..534d25a 100644 --- a/inst/js/adjust_grid.js +++ b/inst/js/adjust_grid.js @@ -49,7 +49,7 @@ export function adjust_grid(ns) { rows.forEach((row, index) => { if (row) { row.style.transition = 'all 0.5s ease'; - row.style.gridTemplateColumns = `67px minmax(125px, 1fr) minmax(125px, 1fr) 50px`; //minmax(100px, ${maxWidth}px) + //row.style.gridTemplateColumns = `67px minmax(125px, 1fr) minmax(125px, 1fr) minmax(50px, auto)`; // ${maxWidth}px } else { console.warn(`Row ${index} is undefined`); } From 0e30bc7c86277c0894113b55fd2f66dfedfea128 Mon Sep 17 00:00:00 2001 From: jenna-a2ai Date: Tue, 19 Nov 2024 15:46:19 +0000 Subject: [PATCH 05/15] custom options -> options --- R/app_01_assign.R | 2 +- R/app_02_resolve.R | 2 +- R/app_03_record.R | 2 +- R/custom_options.R | 18 +++++------------- 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/R/app_01_assign.R b/R/app_01_assign.R index 1dd50ef..d391b9b 100644 --- a/R/app_01_assign.R +++ b/R/app_01_assign.R @@ -10,7 +10,7 @@ #' @export ghqc_assign_app <- function() { if (!exists("info_repo_path", .le)) ghqc_set_info_repo() - get_custom_options() + get_options() # error handling before starting app root_dir <- rproj_root_dir() diff --git a/R/app_02_resolve.R b/R/app_02_resolve.R index 223d12e..fef413b 100644 --- a/R/app_02_resolve.R +++ b/R/app_02_resolve.R @@ -13,7 +13,7 @@ #' @export ghqc_resolve_app <- function() { if (!exists("info_repo_path", .le)) ghqc_set_info_repo() - get_custom_options() + get_options() # error handling before starting app remote <- check_github_credentials() diff --git a/R/app_03_record.R b/R/app_03_record.R index 8b8586a..9da6a6c 100644 --- a/R/app_03_record.R +++ b/R/app_03_record.R @@ -8,7 +8,7 @@ #' @export ghqc_record_app <- function() { if (!exists("info_repo_path", .le)) ghqc_set_info_repo() - get_custom_options() + get_options() # error handling before starting app remote <- check_github_credentials() diff --git a/R/custom_options.R b/R/custom_options.R index f3f1797..4872896 100644 --- a/R/custom_options.R +++ b/R/custom_options.R @@ -1,5 +1,4 @@ get_checklist_display_name_var <- function(capitalized = FALSE, plural = FALSE) { - #browser() checklist_display_name_var <- .le$checklist_display_name_var if (is.null(checklist_display_name_var)) { @@ -33,19 +32,12 @@ get_prepended_checklist_note <- function() { return(prepended_checklist_note) } -# get_dne_var <- function(capitalized = FALSE) { -# dne_var <- .le$dne_var -# -# } +get_options <- function() { + options_yaml <- file.path(.le$info_repo_path, "options.yaml") + options <- yaml::read_yaml(options_yaml) - -get_custom_options <- function() { - custom_options_yaml <- file.path(.le$info_repo_path, "custom_options.yaml") - custom_options <- yaml::read_yaml(custom_options_yaml) - custom_options - - lapply(names(custom_options), function(option_key) { - option_value <- custom_options[[option_key]] + lapply(names(options), function(option_key) { + option_value <- options[[option_key]] assign(option_key, option_value, envir = .le) }) } From 53f6e8d1037da207ff0512432a9642eab531c078 Mon Sep 17 00:00:00 2001 From: jenna-a2ai Date: Tue, 19 Nov 2024 15:56:53 +0000 Subject: [PATCH 06/15] change style in checklist placeholder --- R/app_01_assign_utils.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/R/app_01_assign_utils.R b/R/app_01_assign_utils.R index ec70069..063afc0 100644 --- a/R/app_01_assign_utils.R +++ b/R/app_01_assign_utils.R @@ -60,7 +60,8 @@ render_selected_list <- function(input, ns, iv, items = NULL, checklist_choices choices = c("", checklist_choices), #select checklist (required) width = "100%", selected = NULL, # Ensures no default selection - options = list(placeholder = get_checklist_display_name_var(capitalized = TRUE)) + options = list(placeholder = get_checklist_display_name_var(capitalized = TRUE)), + style = "white-space: normal; overflow: visible; text-overflow: clip; word-wrap: break-word;" ) button_input <- actionButton( From 39a4042014bc26afc8af070a8d53a7f434cc0535 Mon Sep 17 00:00:00 2001 From: jenna-a2ai Date: Tue, 19 Nov 2024 16:41:03 +0000 Subject: [PATCH 07/15] ui changes --- R/app_01_assign_server.R | 3 +-- R/app_01_assign_utils.R | 14 +++++++------- inst/css/styles.css | 11 +++++++---- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/R/app_01_assign_server.R b/R/app_01_assign_server.R index 2883981..692dc5c 100644 --- a/R/app_01_assign_server.R +++ b/R/app_01_assign_server.R @@ -11,7 +11,6 @@ NULL ghqc_assign_server <- function(id, remote, root_dir, checklists, org, repo, members, milestone_list) { iv <- shinyvalidate::InputValidator$new() - observe({ req(remote, root_dir) waiter_hide() @@ -207,7 +206,7 @@ return "
" + escape(item.username) + "
" actionButton(ns("file_info"), label = HTML(glue::glue("Preview all available {get_checklist_display_name_var(plural = TRUE)}")), class = "preview-button", - style = "min-width: auto; display: inline-block; text-align: center; line-height: 2em; height: 2em;" + style = "min-width: auto; display: inline-block; text-align: right; line-height: 2em; height: 2em;" ) #actionButton ) #div diff --git a/R/app_01_assign_utils.R b/R/app_01_assign_utils.R index 063afc0..86a3477 100644 --- a/R/app_01_assign_utils.R +++ b/R/app_01_assign_utils.R @@ -55,15 +55,15 @@ render_selected_list <- function(input, ns, iv, items = NULL, checklist_choices ) checklist_input <- selectizeInput( - ns(checklist_input_id), - label = NULL, - choices = c("", checklist_choices), #select checklist (required) - width = "100%", - selected = NULL, # Ensures no default selection - options = list(placeholder = get_checklist_display_name_var(capitalized = TRUE)), - style = "white-space: normal; overflow: visible; text-overflow: clip; word-wrap: break-word;" + ns(checklist_input_id), + label = NULL, + choices = c("", checklist_choices), + width = "100%", + selected = NULL, + options = list(placeholder = get_checklist_display_name_var(capitalized = TRUE)) ) + button_input <- actionButton( ns(button_input_id), label = HTML("Preview file
contents
"), diff --git a/inst/css/styles.css b/inst/css/styles.css index c738ad0..7aa5334 100644 --- a/inst/css/styles.css +++ b/inst/css/styles.css @@ -146,11 +146,14 @@ div[id$="-main_container"] { transition: 0.5s; } -/* -.item-a { - white-space: nowrap; + +.item-c { + white-space: normal; + overflow: visible; + text-overflow: clip; + word-wrap: break-word; } -*/ + .flex-container { display: flex; From e52c295d9421950265f4651ce49e74ee8b9ca6f4 Mon Sep 17 00:00:00 2001 From: jenna-a2ai Date: Tue, 19 Nov 2024 17:38:18 +0000 Subject: [PATCH 08/15] stop assignees dropdown from wrapping --- inst/css/styles.css | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/inst/css/styles.css b/inst/css/styles.css index 7aa5334..41f9a78 100644 --- a/inst/css/styles.css +++ b/inst/css/styles.css @@ -147,14 +147,10 @@ div[id$="-main_container"] { } -.item-c { - white-space: normal; - overflow: visible; - text-overflow: clip; - word-wrap: break-word; +.item-b { + white-space: nowrap; } - .flex-container { display: flex; align-items: center; From c73a7096235b0f578fd61d19fc3a564a7fe2cb2d Mon Sep 17 00:00:00 2001 From: jenna-a2ai Date: Tue, 19 Nov 2024 18:24:20 +0000 Subject: [PATCH 09/15] changes info_repo to config_repo and GHQC_INFO_REPO to GHQC_CONFIG_REPO --- NAMESPACE | 2 +- R/app_01_assign.R | 2 +- R/app_02_resolve.R | 2 +- R/app_03_record.R | 2 +- R/create_yaml.R | 2 +- R/custom_options.R | 2 +- R/info_repo.R | 38 +++++++++++++++++++------------------- R/scrape.R | 2 +- man/ghqc_set_info_repo.Rd | 10 +++++----- 9 files changed, 31 insertions(+), 31 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 02ccf0d..6f872f4 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -3,7 +3,7 @@ export(ghqc_assign_app) export(ghqc_record_app) export(ghqc_resolve_app) -export(ghqc_set_info_repo) +export(ghqc_set_config_repo) import(shiny) importFrom(dplyr,"%>%") importFrom(dplyr,case_when) diff --git a/R/app_01_assign.R b/R/app_01_assign.R index d391b9b..53c9f84 100644 --- a/R/app_01_assign.R +++ b/R/app_01_assign.R @@ -9,7 +9,7 @@ #' @import shiny #' @export ghqc_assign_app <- function() { - if (!exists("info_repo_path", .le)) ghqc_set_info_repo() + if (!exists("config_repo_path", .le)) ghqc_set_config_repo() get_options() # error handling before starting app diff --git a/R/app_02_resolve.R b/R/app_02_resolve.R index fef413b..2a54d2c 100644 --- a/R/app_02_resolve.R +++ b/R/app_02_resolve.R @@ -12,7 +12,7 @@ #' @importFrom log4r warn error info debug #' @export ghqc_resolve_app <- function() { - if (!exists("info_repo_path", .le)) ghqc_set_info_repo() + if (!exists("config_repo_path", .le)) ghqc_set_config_repo() get_options() # error handling before starting app diff --git a/R/app_03_record.R b/R/app_03_record.R index 9da6a6c..07d837c 100644 --- a/R/app_03_record.R +++ b/R/app_03_record.R @@ -7,7 +7,7 @@ #' @import shiny #' @export ghqc_record_app <- function() { - if (!exists("info_repo_path", .le)) ghqc_set_info_repo() + if (!exists("config_repo_path", .le)) ghqc_set_config_repo() get_options() # error handling before starting app diff --git a/R/create_yaml.R b/R/create_yaml.R index 4ea4138..b2bc5ac 100644 --- a/R/create_yaml.R +++ b/R/create_yaml.R @@ -1,5 +1,5 @@ get_checklists <- function() { - checklists_path <- file.path(.le$info_repo_path, "checklists") + checklists_path <- file.path(.le$config_repo_path, "checklists") yaml_checklists <- list.files(checklists_path, pattern = "\\.ya?ml$", full.names = TRUE) custom_checklist <- system.file("default_checklist", "custom.yaml", package = "ghqc.app") yaml_checklists <- c(yaml_checklists, custom_checklist) diff --git a/R/custom_options.R b/R/custom_options.R index 4872896..68a0ff9 100644 --- a/R/custom_options.R +++ b/R/custom_options.R @@ -33,7 +33,7 @@ get_prepended_checklist_note <- function() { } get_options <- function() { - options_yaml <- file.path(.le$info_repo_path, "options.yaml") + options_yaml <- file.path(.le$config_repo_path, "options.yaml") options <- yaml::read_yaml(options_yaml) lapply(names(options), function(option_key) { diff --git a/R/info_repo.R b/R/info_repo.R index 0e64fcc..7a5b836 100644 --- a/R/info_repo.R +++ b/R/info_repo.R @@ -1,42 +1,42 @@ #' set the repo that stores the ghqc info #' @param repo_path path to the git repo storing ghqc information #' @export -ghqc_set_info_repo <- function(repo_path = file.path("~/.local/share/ghqc", info_repo_name())) { +ghqc_set_config_repo <- function(repo_path = file.path("~/.local/share/ghqc", config_repo_name())) { not_files <- NULL if (!file.exists(file.path(repo_path, "checklists"))) not_files <- append(not_files, "Checklists directory") if (!file.exists(file.path(repo_path, "logo.png"))) not_files <- append(not_files, "logo.png") - if (!is.null(not_files)) info_repo_files_not_found(not_files, repo_path) - assign("info_repo_path", repo_path, envir = .le) + if (!is.null(not_files)) config_repo_files_not_found(not_files, repo_path) + assign("config_repo_path", repo_path, envir = .le) } -info_repo_files_not_found <- function(not_files, repo_path) { +config_repo_files_not_found <- function(not_files, repo_path) { error(.le$logger, glue::glue("{paste(not_files, collapse = ' and ')} not found in {repo_path}. Please ensure file(s) are present before continuing")) rlang::abort(glue::glue("{paste(not_files, collapse = ' and ')} not found in {repo_path}. Please ensure file(s) are present before continuing")) } -check_ghqc_info_repo_exists <- function() { - if (!file.exists("~/.Renviron")) info_repo_not_found() +check_ghqc_config_repo_exists <- function() { + if (!file.exists("~/.Renviron")) config_repo_not_found() readRenviron("~/.Renviron") - info_repo <- Sys.getenv("GHQC_INFO_REPO") - if (info_repo == "") info_repo_not_found() - if (substr(info_repo, 1, 8) != "https://") { - error(.le$logger, glue::glue("GHQC_INFO_REPO ({info_repo}) does not start with 'https://'")) - rlang::abort(sprintf("GHQC_INFO_REPO (%s) does not start with 'https://'"), info_repo) + config_repo <- Sys.getenv("GHQC_CONFIG_REPO") + if (config_repo == "") config_repo_not_found() + if (substr(config_repo, 1, 8) != "https://") { + error(.le$logger, glue::glue("GHQC_CONFIG_REPO ({config_repo}) does not start with 'https://'")) + rlang::abort(sprintf("GHQC_CONFIG_REPO (%s) does not start with 'https://'"), config_repo) } } -info_repo_name <- function() { - gsub(".git", "", basename(info_repo_url())) +config_repo_name <- function() { + gsub(".git", "", basename(config_repo_url())) } -info_repo_url <- function() { - check_ghqc_info_repo_exists() - Sys.getenv("GHQC_INFO_REPO") +config_repo_url <- function() { + check_ghqc_config_repo_exists() + Sys.getenv("GHQC_CONFIG_REPO") } -info_repo_not_found <- function() { - error(.le$logger, "GHQC_INFO_REPO not found. Please set in ~/.Renviron") - rlang::abort(message = "GHQC_INFO_REPO not found. Please set in ~/.Renviron") +config_repo_not_found <- function() { + error(.le$logger, "GHQC_CONFIG_REPO not found. Please set in ~/.Renviron") + rlang::abort(message = "GHQC_CONFIG_REPO not found. Please set in ~/.Renviron") } diff --git a/R/scrape.R b/R/scrape.R index 6216d8d..347c00e 100644 --- a/R/scrape.R +++ b/R/scrape.R @@ -356,7 +356,7 @@ create_intro <- function(repo, milestone_names) { date <- format(Sys.Date(), '%B %d, %Y') milestone_names_list <- glue::glue_collapse(milestone_names, sep = ", ") # - image_path <- file.path(.le$info_repo_path, "logo.png") + image_path <- file.path(.le$config_repo_path, "logo.png") intro <- glue::glue( "--- title: \"QC Record: {milestone_names_list}\" diff --git a/man/ghqc_set_info_repo.Rd b/man/ghqc_set_info_repo.Rd index 12c771c..e9835a6 100644 --- a/man/ghqc_set_info_repo.Rd +++ b/man/ghqc_set_info_repo.Rd @@ -1,11 +1,11 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/info_repo.R -\name{ghqc_set_info_repo} -\alias{ghqc_set_info_repo} +% Please edit documentation in R/config_repo.R +\name{ghqc_set_config_repo} +\alias{ghqc_set_config_repo} \title{set the repo that stores the ghqc info} \usage{ -ghqc_set_info_repo( - repo_path = file.path("~/.local/share/ghqc", info_repo_name()) +ghqc_set_config_repo( + repo_path = file.path("~/.local/share/ghqc", config_repo_name()) ) } \arguments{ From 8f45f20876b888fbcc340711a9227de183fdabc3 Mon Sep 17 00:00:00 2001 From: jenna-a2ai Date: Tue, 19 Nov 2024 19:39:33 +0000 Subject: [PATCH 10/15] document ghqc_set_config_repo --- NAMESPACE | 1 + man/{ghqc_set_info_repo.Rd => ghqc_set_config_repo.Rd} | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) rename man/{ghqc_set_info_repo.Rd => ghqc_set_config_repo.Rd} (89%) diff --git a/NAMESPACE b/NAMESPACE index 6f872f4..be286af 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -16,6 +16,7 @@ importFrom(fs,is_file) importFrom(gert,git_ahead_behind) importFrom(gert,git_fetch) importFrom(gert,git_status) +importFrom(gh,gh) importFrom(glue,glue) importFrom(jsTreeR,jstree) importFrom(jsTreeR,jstreeOutput) diff --git a/man/ghqc_set_info_repo.Rd b/man/ghqc_set_config_repo.Rd similarity index 89% rename from man/ghqc_set_info_repo.Rd rename to man/ghqc_set_config_repo.Rd index e9835a6..2920c20 100644 --- a/man/ghqc_set_info_repo.Rd +++ b/man/ghqc_set_config_repo.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/config_repo.R +% Please edit documentation in R/info_repo.R \name{ghqc_set_config_repo} \alias{ghqc_set_config_repo} \title{set the repo that stores the ghqc info} From 1f4b994b745ce5bdcddf71e995293f3e4ac44ce3 Mon Sep 17 00:00:00 2001 From: jenna-a2ai Date: Tue, 19 Nov 2024 19:41:39 +0000 Subject: [PATCH 11/15] makes options.yaml not required --- R/custom_options.R | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/R/custom_options.R b/R/custom_options.R index 68a0ff9..2606b2d 100644 --- a/R/custom_options.R +++ b/R/custom_options.R @@ -33,13 +33,19 @@ get_prepended_checklist_note <- function() { } get_options <- function() { - options_yaml <- file.path(.le$config_repo_path, "options.yaml") - options <- yaml::read_yaml(options_yaml) - - lapply(names(options), function(option_key) { - option_value <- options[[option_key]] - assign(option_key, option_value, envir = .le) + # put in tryCatch because file may not exist + tryCatch({ + options_yaml <- file.path(.le$config_repo_path, "options.yaml") + options <- yaml::read_yaml(options_yaml) + + lapply(names(options), function(option_key) { + option_value <- options[[option_key]] + assign(option_key, option_value, envir = .le) + }) + }, error = function(e) { + return() }) + } capitalize <- function(word) { From d86a694d275691b36ebcf843c20d7b735f4870b9 Mon Sep 17 00:00:00 2001 From: jenna-a2ai Date: Tue, 19 Nov 2024 20:27:08 +0000 Subject: [PATCH 12/15] updates version to 0.3.0.9000 and adds to NEWS.md --- DESCRIPTION | 2 +- NEWS.md | 90 +++++++++++++++++++++++++++++------------------------ 2 files changed, 50 insertions(+), 42 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index bedb0d7..7055c99 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: ghqc.app Title: Create QC Checklists in Github Issues -Version: 0.2.0.9000 +Version: 0.3.0.9000 Authors@R: c( person("Jenna", "Johnson", email = "jenna@a2-ai.com", role = c("aut", "cre")), person("Anne", "Zheng", email = "anne@a2-ai.com", role = c("aut")), diff --git a/NEWS.md b/NEWS.md index 8438187..1d7ac03 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,109 +1,117 @@ +# ghqc.app 0.3.0 + +- Updated the custom configuration options repository (now `GHQC_OPTIONS_REPO`) check to reflect the following changes: + - The "note" file within the custom configuration repository is now `prepended_checklist_note` within "options.yaml" + - `checklist_display_name_var` in "options.yaml" provides option to change the name in which the QC checklists are referred to as. + # ghqc.app 0.2.0 Inclusive of 0.1.9, 0.1.10, 0.1.11 changes: -- Adding the branch and a link to the file contents at the start of QC to the Metadata section of Issues created by the Assign app. Also added links to the file contents at the previous and current commits in the metadata section of the resolve app comments. -- Adds "ghqc" label to all GitHub Issues created by ghqc. Only Issues with this label, and the Milestones containing them, will be viewable/selectable in the apps. This change is NOT backward compatible with Issues/Milestones created in previous versions -- Clarifies language in Warning and Error modals for all three apps +- Adding the branch and a link to the file contents at the start of QC to the Metadata section of Issues created by the Assign app. Also added links to the file contents at the previous and current commits in the metadata section of the resolve app comments. +- Adds "ghqc" label to all GitHub Issues created by ghqc. Only Issues with this label, and the Milestones containing them, will be viewable/selectable in the apps. This change is NOT backward compatible with Issues/Milestones created in previous versions +- Clarifies language in Warning and Error modals for all three apps # ghqc.app 0.1.11 -- Adding the branch and a link to the file contents at the start of QC to the Metadata section of Issues created by the Assign app. Also added links to the file contents at the previous and current commits in the metadata section of the resolve app comments. +- Adding the branch and a link to the file contents at the start of QC to the Metadata section of Issues created by the Assign app. Also added links to the file contents at the previous and current commits in the metadata section of the resolve app comments. # ghqc.app 0.1.10 -- Adds "ghqc" label to all GitHub Issues created by ghqc. Only Issues with this label, and the Milestones containing them, will be viewable/selectable in the apps. This change is NOT backward compatible with Issues/Milestones created in previous versions +- Adds "ghqc" label to all GitHub Issues created by ghqc. Only Issues with this label, and the Milestones containing them, will be viewable/selectable in the apps. This change is NOT backward compatible with Issues/Milestones created in previous versions # ghqc.app 0.1.9 -- Clarifies language in Warning and Error modals for all three apps +- Clarifies language in Warning and Error modals for all three apps -# ghqc.app 0.1.8 +# ghqc.app 0.1.8 -- Removes reset button in record app modal for users to click after closing milestones when no closed milestones exist (was buggy in viewer panel) +- Removes reset button in record app modal for users to click after closing milestones when no closed milestones exist (was buggy in viewer panel) # ghqc.app 0.1.7 -- Fixes bug in rendered reports in which a maximum height for logos wasn't set to prevent overlapping header lines and header text. +- Fixes bug in rendered reports in which a maximum height for logos wasn't set to prevent overlapping header lines and header text. # ghqc.app 0.1.6 -- Fixes bug in record app for previewing markdown files (same bug and solution as in 0.1.4) +- Fixes bug in record app for previewing markdown files (same bug and solution as in 0.1.4) # ghqc.app 0.1.5 -- Fixes bug in assign and resolve apps - error checking did not catch remote changes to the directory because checks did not git fetch first +- Fixes bug in assign and resolve apps - error checking did not catch remote changes to the directory because checks did not git fetch first # ghqc.app 0.1.4 -- Fixes bug in resolve app for previewing markdown files +- Fixes bug in resolve app for previewing markdown files # ghqc.app 0.1.3 -- Changes "No Existing Milestones"" to "No Open Milestones" in ghqc_assign_app() Existing Milestones dropdown menu +- Changes "No Existing Milestones"" to "No Open Milestones" in ghqc_assign_app() Existing Milestones dropdown menu # ghqc.app 0.1.2 -- Fixes bug in record app warning modal pop-up for unclosed milestones/issues/checklist items: Milestone link wasn't clickable -- Improves "No closed milestones" modal pop-up warning in record app. Language change to "It is recommended to close milestones" and adds a reset link to modal for users to click after closing milestones. +- Fixes bug in record app warning modal pop-up for unclosed milestones/issues/checklist items: Milestone link wasn't clickable +- Improves "No closed milestones" modal pop-up warning in record app. Language change to "It is recommended to close milestones" and adds a reset link to modal for users to click after closing milestones. # ghqc.app 0.1.1 -- In the case when someone sets the standard gh environment variable GITHUB_API_URL, each app checks if this URL matches the actual set remote URL. The function that gets the GITHUB_API_URL did not explicitly return a value. +- In the case when someone sets the standard gh environment variable GITHUB_API_URL, each app checks if this URL matches the actual set remote URL. The function that gets the GITHUB_API_URL did not explicitly return a value. -- Small grammar fix in error message from apps in the case that the checklists directory isn't in the cloned info repo. +- Small grammar fix in error message from apps in the case that the checklists directory isn't in the cloned info repo. # ghqc.app 0.0.0.9011 -- rename ghqc to ghqc.app and ghqc.launcher to ghqc +- rename ghqc to ghqc.app and ghqc.launcher to ghqc # ghqc 0.0.0.9010 -- terminology changed to match GitHub terminology like "Issue" and "Milestone" +- terminology changed to match GitHub terminology like "Issue" and "Milestone" -- git commit terminology changed from "reference" and "comparator" to "previous" and "current", respectively +- git commit terminology changed from "reference" and "comparator" to "previous" and "current", respectively -- current commit moved to top of metadata section +- current commit moved to top of metadata section -- metadata sections moved to top of issue/comment bodies +- metadata sections moved to top of issue/comment bodies -- "Create" app renamed to "Assign" app +- "Create" app renamed to "Assign" app -- "git sha" in metadata renamed to "initial qc commit" and moved to top of metadata section +- "git sha" in metadata renamed to "initial qc commit" and moved to top of metadata section # ghqc 0.0.0.9009 ## New features -- ghqc pulls client-specific information from a pre-existing repo using the environment variable `GIT_CLIENT_URL`, which is set equal to the https code link to the relevant github repo. +- ghqc pulls client-specific information from a pre-existing repo using the environment variable `GIT_CLIENT_URL`, which is set equal to the https code link to the relevant github repo. # ghqc 0.0.0.9008 ## New features -- ghqcLauncher is now ghqc.launcher to comply with standardized helper package naming conventions. +- ghqcLauncher is now ghqc.launcher to comply with standardized helper package naming conventions. + +- The report function is now a shiny app that can run in ghqc.launcher + +- The git credential authentication function is more robust in each case when + + 1) Git is already authenticated, + 2) Git isn't already authenticated, and + 3) Git is mis-authenticated. + +- Error handling for the git repo and Rproject is now more robust -- The report function is now a shiny app that can run in ghqc.launcher +- The sidebar in `ghqc_create_app()` now scrolls for easy reading of long file and directory names -- The git credential authentication function is more robust in each case when - 1) Git is already authenticated, - 2) Git isn't already authenticated, and - 3) Git is mis-authenticated. +- ghqc can function with multiple remotes set for a given repo, and the app selects the remote in the following hierarchy: -- Error handling for the git repo and Rproject is now more robust + 1) If a single remote exists, it selects it -- The sidebar in `ghqc_create_app()` now scrolls for easy reading of long file and directory names + 2) Else, if multiple remotes exist: -- ghqc can function with multiple remotes set for a given repo, and the app selects the remote in the following hierarchy: - 1) If a single remote exists, it selects it - - 2) Else, if multiple remotes exist: - - - if the environment variable GHQC_REMOTE_NAME exists, it selects the one with that name + - if the environment variable GHQC_REMOTE_NAME exists, it selects the one with that name - - else, if a remote named "origin" exists, it selects it + - else, if a remote named "origin" exists, it selects it - - else, it uses the first remote in the list of remotes + - else, it uses the first remote in the list of remotes # ghqc 0.0.0.9007 From ce1209950454a1484380a224bb4b2ec03e9317b7 Mon Sep 17 00:00:00 2001 From: jenna-a2ai Date: Tue, 19 Nov 2024 22:00:12 +0000 Subject: [PATCH 13/15] makes logo.png in config repo not required; QC records without logos just have blank headers --- R/{info_repo.R => config_repo.R} | 3 ++- R/scrape.R | 32 +++++++++++++++++++++++--------- 2 files changed, 25 insertions(+), 10 deletions(-) rename R/{info_repo.R => config_repo.R} (92%) diff --git a/R/info_repo.R b/R/config_repo.R similarity index 92% rename from R/info_repo.R rename to R/config_repo.R index 7a5b836..6fc944a 100644 --- a/R/info_repo.R +++ b/R/config_repo.R @@ -4,7 +4,8 @@ ghqc_set_config_repo <- function(repo_path = file.path("~/.local/share/ghqc", config_repo_name())) { not_files <- NULL if (!file.exists(file.path(repo_path, "checklists"))) not_files <- append(not_files, "Checklists directory") - if (!file.exists(file.path(repo_path, "logo.png"))) not_files <- append(not_files, "logo.png") + # allow the logo to be optional + #if (!file.exists(file.path(repo_path, "logo.png"))) not_files <- append(not_files, "logo.png") if (!is.null(not_files)) config_repo_files_not_found(not_files, repo_path) assign("config_repo_path", repo_path, envir = .le) } diff --git a/R/scrape.R b/R/scrape.R index 347c00e..b3c6744 100644 --- a/R/scrape.R +++ b/R/scrape.R @@ -355,8 +355,27 @@ create_intro <- function(repo, milestone_names) { author <- Sys.info()[["user"]] date <- format(Sys.Date(), '%B %d, %Y') milestone_names_list <- glue::glue_collapse(milestone_names, sep = ", ") - # + image_path <- file.path(.le$config_repo_path, "logo.png") + + logo_exists_extra_header <- { + if (fs::file_exists(image_path)) { + glue::glue(" + - \\fancyhead[R]{{\\includegraphics[width=2cm, height=1.5cm, keepaspectratio]{{{image_path}}}}} + - \\fancyhead[C]{{}} + - \\fancyhead[L]{{}} + - \"\\\\fancypagestyle{{plain}}{{\" + - \"\\\\renewcommand{{\\\\headrulewidth}}{{0.4pt}}\" + - \"}}\"", .trim = FALSE) + } + else { + glue::glue(" + - \\fancyhead[R]{{}} + - \\fancyhead[C]{{}} + - \\fancyhead[L]{{}}", .trim = FALSE) + } + } + intro <- glue::glue( "--- title: \"QC Record: {milestone_names_list}\" @@ -375,17 +394,10 @@ create_intro <- function(repo, milestone_names) { - \\newcolumntype{{R}}[1]{{>{{\\raggedright\\arraybackslash}}p{{#1}}}} - \\newcommand{{\\blandscape}}{{\\begin{{landscape}}}} - \\newcommand{{\\elandscape}}{{\\end{{landscape}}}} - - \\fancyhead[R]{{\\includegraphics[width=2cm, height=1.5cm, keepaspectratio]{{{image_path}}}}} - - \\fancyhead[C]{{}} - - \\fancyhead[L]{{}} - \\setlength{{\\headheight}}{{30pt}} - \\fancyfoot[C]{{Page \\thepage\\ of \\pageref{{LastPage}}}} - \\usepackage{{lastpage}} - - \\lstset{{breaklines=true}} - - \"\\\\fancypagestyle{{plain}}{{\" - - \"\\\\fancyhead[R]{{\\\\includegraphics[width=2cm, height=1.5cm, keepaspectratio]{{{image_path}}}}}\" - - \"\\\\renewcommand{{\\\\headrulewidth}}{{0.4pt}}\" - - \"}}\" + - \\lstset{{breaklines=true}}{logo_exists_extra_header} output: pdf_document: latex_engine: xelatex @@ -398,6 +410,8 @@ create_intro <- function(repo, milestone_names) { \\newpage ") + + return(intro) } From cd59912751667e60d7c92cc94b295bcb68dfe6b4 Mon Sep 17 00:00:00 2001 From: Wes Cummings Date: Wed, 20 Nov 2024 15:12:58 +0000 Subject: [PATCH 14/15] allowing logo to be optional and making checklist directory verification more verbose --- R/config_repo.R | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/R/config_repo.R b/R/config_repo.R index 6fc944a..3ee2d65 100644 --- a/R/config_repo.R +++ b/R/config_repo.R @@ -3,16 +3,23 @@ #' @export ghqc_set_config_repo <- function(repo_path = file.path("~/.local/share/ghqc", config_repo_name())) { not_files <- NULL - if (!file.exists(file.path(repo_path, "checklists"))) not_files <- append(not_files, "Checklists directory") - # allow the logo to be optional - #if (!file.exists(file.path(repo_path, "logo.png"))) not_files <- append(not_files, "logo.png") - if (!is.null(not_files)) config_repo_files_not_found(not_files, repo_path) - assign("config_repo_path", repo_path, envir = .le) -} + if (!file.exists(file.path(repo_path, "checklists"))) { + error(.le$logger, glue::glue("The 'checklists' directory is not found in {repo_path}. Please ensure the directory is present before continuing")) + rlang::abort(glue::glue("The 'checklists' directory is not found in {repo_path}. Please ensure the directory is present before continuing")) + } + + checklist_content <- fs::dir_ls(file.path(repo_path, "checklists"), regexp = "[.]yaml$") + if (length(checklist_content) == 0) { + error(.le$logger, glue::glue("The 'checklists' directory in {repo_path} has no .yaml files. Please ensure the directory is populated before continuing")) + rlang::abort(glue::glue("The 'checklists' directory in {repo_path} has no .yaml files. Please ensure the directory is populated before continuing")) + } + + if (all(grepl("INVALID - ", basename(checklist_content)))) { + error(.le$logger, glue::glue("The 'checklists' directory in {repo_path} has no valid checklists. Please ensure the checklists are properly formatted before continuing")) + rlang::abort(glue::glue("The 'checklists' directory in {repo_path} has no valid checklists. Please ensure the checklists are properly formatted before continuing")) + } -config_repo_files_not_found <- function(not_files, repo_path) { - error(.le$logger, glue::glue("{paste(not_files, collapse = ' and ')} not found in {repo_path}. Please ensure file(s) are present before continuing")) - rlang::abort(glue::glue("{paste(not_files, collapse = ' and ')} not found in {repo_path}. Please ensure file(s) are present before continuing")) + assign("config_repo_path", repo_path, envir = .le) } check_ghqc_config_repo_exists <- function() { From 9012d2be30f43e81b5ff51d79b492eb0305661f9 Mon Sep 17 00:00:00 2001 From: Wes Cummings Date: Wed, 20 Nov 2024 15:29:35 +0000 Subject: [PATCH 15/15] Adding more handling around yaml reading and removing old custom configuration reading --- R/custom_options.R | 9 ++-- R/git_client_info.R | 102 -------------------------------------------- 2 files changed, 5 insertions(+), 106 deletions(-) delete mode 100644 R/git_client_info.R diff --git a/R/custom_options.R b/R/custom_options.R index 2606b2d..24d8fea 100644 --- a/R/custom_options.R +++ b/R/custom_options.R @@ -34,18 +34,19 @@ get_prepended_checklist_note <- function() { get_options <- function() { # put in tryCatch because file may not exist + options_yaml <- file.path(.le$config_repo_path, "options.yaml") + if (!fs::file_exists(options_yaml)) return() tryCatch({ - options_yaml <- file.path(.le$config_repo_path, "options.yaml") - options <- yaml::read_yaml(options_yaml) + options <- unlist(yaml::read_yaml(options_yaml)) lapply(names(options), function(option_key) { option_value <- options[[option_key]] assign(option_key, option_value, envir = .le) }) }, error = function(e) { - return() + error("option.yaml could not be read") + rlang::abort(parent = e$parent) }) - } capitalize <- function(word) { diff --git a/R/git_client_info.R b/R/git_client_info.R deleted file mode 100644 index 4bafcbd..0000000 --- a/R/git_client_info.R +++ /dev/null @@ -1,102 +0,0 @@ -.lci <- new.env() - -#' @importFrom log4r warn error info debug -get_client_git_url <- function() { - git_url <- Sys.getenv("GIT_CLIENT_URL") - - # error if CLIENT_INFO_URL not set - if (length(git_url) == 0){ - error(.le$logger, "No client github url found. Please set GIT_CLIENT_URL environmental variable, likely in your ~/.Renviron file.") - rlang::abort(message = "No client github url found. Please set GIT_CLIENT_URL environmental variable, likely in your ~/.Renviron file.") - } - - # error if not https - url_starts_with_https <- stringr::str_starts(git_url, "https://") - if (!url_starts_with_https) { - error(.le$logger, glue::glue("Retrieved GIT_CLIENT_URL: {git_url} does not start with https")) - rlang::abort(message = glue::glue("Retrieved GIT_CLIENT_URL: {git_url} does not start with https")) - } - git_url -} - -#' @importFrom log4r warn error info debug -check_client_local <- function(git_url) { - client_repo_name <- get_remote_name(git_url) - client_repo_path <- file.path("~",client_repo_name) - - if (!file.exists(client_repo_path)) { - # Case 1: Repo not in home dir, cloning down - debug(.le$logger, glue::glue("{client_repo_name} not found in home directory. Attempting to clone {git_url} to {client_repo_path}...")) - tryCatch( - { - gert::git_clone(git_url, path = client_repo_path) - info(.le$logger, glue::glue("Successfully cloned {client_repo_name}")) - }, error = function(e) { - error(.le$logger, glue::glue("Clone of {client_repo_name} was not successful")) - rlang::abort(message = e$message) - } - ) - } # if client repo not cloned - else { - remote_updates <- remote_repo_updates(client_repo_path) - local_updates <- local_repo_updates(client_repo_path) - - # if local changes - if (local_updates) { - stash <- gert::git_stash_save(repo = client_repo_path) - info(.le$logger, glue::glue("Stashed local changes to {client_repo_path}")) - } - - # if remote changes - if (remote_updates) { - # Case 2: Repo in home dir, but local or remote changes - debug(.le$logger, "Most recent remote commit ({remote_commit_id}) does not match local commit ({local_commit_id}). Attempting to pull down update to {client_repo_path}...") - tryCatch( - { - gert::git_pull(repo = client_repo_path) - info(.le$logger, glue::glue("Update has been successfully pulled down to {client_repo_path}")) - }, error = function(e) { - error(.le$logger, glue::glue("Update was unsuccessfully pulled down. Attempted to pull {client_repo_name} remote commit id {remote_commit_id} to {client_repo_path}")) - rlang::abort(.le$logger, message = e$message) - } - ) - } - - if (!remote_updates && !local_updates) { - info(.le$logger, "No local or remote updates to ghqc storage repo") - } - - } # else, client dir has already been cloned - - return(client_repo_path) -} - -#' @importFrom log4r warn error info debug -local_repo_updates <- function(client_repo_path) { - status <- gert::git_status(repo = client_repo_path) - local_repo_updates <- "modified" %in% status$status - if (local_repo_updates) { - info(.le$logger, glue::glue("Detected local changes to {client_repo_path}")) - } - return(local_repo_updates) -} - -#' @importFrom log4r warn error info debug -remote_repo_updates <- function(client_repo_path) { - remote_commit_id <- gert::git_remote_ls(repo = client_repo_path)$oid[1] - local_commit_id <- gert::git_info(repo = client_repo_path)$commit - remote_repo_updates <- remote_commit_id != local_commit_id - return(remote_repo_updates) -} - -#' @importFrom log4r warn error info debug -load_client_info <- function(){ - if (file.exists("~/.Renviron")) readRenviron("~/.Renviron") - - # get client url from ~./Renviron - git_url <- get_client_git_url() - - # check if client local is cloned and most up to date commit - client_repo_path <- check_client_local(git_url) - assign("client_repo_path", client_repo_path, envir = .lci) -}