diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index dffb85e7..ff2b7045 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -1,4 +1,4 @@ -# Workflow derived from https://github.com/r-lib/actions/tree/master/examples +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help on: push: @@ -9,6 +9,8 @@ on: name: test-coverage +permissions: read-all + jobs: test-coverage: runs-on: ubuntu-latest @@ -24,21 +26,45 @@ jobs: sudo apt-get update sudo apt-get install -y texlive-xetex - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: r-lib/actions/setup-pandoc@v2 - uses: r-lib/actions/setup-r@v2 with: - use-public-rspm: true + use-public-rspm: false r-version: 'renv' - uses: r-lib/actions/setup-renv@v2 - - name: Install riskassessment - shell: bash - run: R CMD INSTALL --preclean . - - name: Test coverage - run: covr::codecov() + run: | + cov <- covr::package_coverage( + quiet = FALSE, + clean = FALSE, + install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package") + ) + covr::to_cobertura(cov) shell: Rscript {0} + + - uses: codecov/codecov-action@v4 + with: + fail_ci_if_error: ${{ github.event_name != 'pull_request' && true || false }} + file: ./cobertura.xml + plugin: noop + disable_search: true + token: ${{ secrets.CODECOV_TOKEN }} + + - name: Show testthat output + if: always() + run: | + ## -------------------------------------------------------------------- + find '${{ runner.temp }}/package' -name 'testthat.Rout*' -exec cat '{}' \; || true + shell: bash + + - name: Upload test results + if: failure() + uses: actions/upload-artifact@v4 + with: + name: coverage-test-failures + path: ${{ runner.temp }}/package diff --git a/DESCRIPTION b/DESCRIPTION index d21963c0..66601712 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: riskassessment Title: A web app designed to interface with the `riskmetric` package -Version: 3.1.0 +Version: 3.1.1 Authors@R: c( person("Aaron", "Clark", role = c("aut", "cre"), email = "clark.aaronchris@gmail.com"), person("Jeff", "Thompson", role = c("aut"), email = "jeff.thompson51317@gmail.com", comment = "Co-Lead"), diff --git a/NEWS.md b/NEWS.md index 8882138a..678888e2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,10 @@ +# riskassessment 3.1.1 + +* Added navigation controls in Function Explorer tab (#644) +* Fixed bug that crashed the Package Dependencies page for pkgs without any dependency info available (#802) +* Fixed bug that incorrectly displayed 0 dependencies as 1 (#805) +* Fixed bug that kept full list of available packages from populating (#776) + # riskassessment 3.1.0 ### User Enhancements diff --git a/R/app_server.R b/R/app_server.R index 98bc3e97..6a9c86bf 100644 --- a/R/app_server.R +++ b/R/app_server.R @@ -11,9 +11,20 @@ app_server <- function(input, output, session) { old <- options() onStop(function() { - options(old) - }) - options(repos = get_db_config("package_repo")) + options(c( + # Unsets available packages filter if unset previously. Will be overriden + # otherwise. + list(available_packages_filters = NULL), + old + )) + }) + options( + # Set session repo to value specified in configuration file + repos = get_db_config("package_repo"), + # Removes filters based on R version, OS type, sub-architecture. Only + # duplicates will be removed from the available package list + available_packages_filters = "duplicates" + ) # Collect user info. user <- reactiveValues() diff --git a/R/mod_code_explorer.R b/R/mod_code_explorer.R index 7d0ebffd..2259f215 100644 --- a/R/mod_code_explorer.R +++ b/R/mod_code_explorer.R @@ -31,7 +31,7 @@ mod_code_explorer_server <- function(id, selected_pkg, pkgarchive = reactiveVal( showHelperMessage(message = glue::glue("Source code not available for {{{selected_pkg$name()}}}")) } else { div(introJSUI(NS(id, "introJS")), - br(), + br(), fluidRow( column(3, wellPanel( @@ -69,7 +69,28 @@ mod_code_explorer_server <- function(id, selected_pkg, pkgarchive = reactiveVal( div(id = ns("file_viewer"), uiOutput(ns("file_output"), class = "file_browser"), style = "height: 62vh; overflow: auto; border: 1px solid var(--bs-border-color-translucent);" - ) + ), + br(), + fluidRow(style = "height:35px !important;", + column(4,offset = 8, + conditionalPanel( + condition = "typeof(window.$highlights_list) != 'undefined' && window.$highlights_list.length > 1", + actionButton(ns("prev_button"),label = "",icon = icon("chevron-left"), + style ="width: 32px !important; + height: 32px !important; + font-size: 16px !important; + line-height: 5px !important; + padding: 0px !important;") |>bslib::tooltip("Previous occurence"), style = "display: inline-block;", + + div(id = "search_index","",style ="display:inline"), + actionButton(ns("next_button"),label = "",icon = icon("chevron-right"), + style = "width: 32px !important; + height: 32px !important; + font-size: 16px !important; + line-height: 5px !important; + padding: 0px !important; + display:inline; + ")|>bslib::tooltip("Next occurence",placement ="right"), style = "display: inline-block;"))) ) ), br(), br(), @@ -127,7 +148,7 @@ mod_code_explorer_server <- function(id, selected_pkg, pkgarchive = reactiveVal( close(con) func_list <- c(input$exported_function, paste0("`", input$exported_function, "`")) highlight_index <- parse_data() %>% - filter(stringr::str_ends(file, input$test_files) & func %in% func_list) %>% + filter(basename(file) == input$test_files & func %in% func_list) %>% pull(line) renderCode(lines, highlight_index) }) %>% @@ -144,7 +165,7 @@ mod_code_explorer_server <- function(id, selected_pkg, pkgarchive = reactiveVal( close(con) func_list <- c(input$exported_function, paste0("`", input$exported_function, "`")) highlight_index <- parse_data() %>% - filter(stringr::str_ends(file, input$source_files) & func %in% func_list) %>% + filter(basename(file) == input$source_files & func %in% func_list) %>% pull(line) renderCode(lines, highlight_index) }) %>% @@ -157,8 +178,12 @@ mod_code_explorer_server <- function(id, selected_pkg, pkgarchive = reactiveVal( con <- archive::archive_read(file.path("tarballs", glue::glue("{selected_pkg$name()}_{selected_pkg$version()}.tar.gz")), file = fp) + Rdfile <-tools::parse_Rd(con) close(con) + shinyjs::runjs(' + $highlights_list = undefined;') + HTML(paste0(utils::capture.output(tools::Rd2HTML(Rdfile, package = c(selected_pkg$name(), selected_pkg$version()), out = "")), collapse = "\n")) @@ -166,7 +191,57 @@ mod_code_explorer_server <- function(id, selected_pkg, pkgarchive = reactiveVal( bindEvent(input$man_files, input$exported_function, ignoreNULL = FALSE) introJSServer("introJS", text = reactive(fe_steps), user, credentials) + search_index_value <- reactiveVal(1) + highlight_list <- reactiveVal(1) + + observeEvent(input$next_button,{ + if (input$next_button > 0){ + shinyjs::runjs(' + var $index =Array.from($highlights_list).findIndex(node => node.isEqualNode($curr_sel)); + if( $index == $highlights_list.length -1) + { + + $curr_sel = $highlights_list[0] + search_index.innerHTML = 1 + " of " + $highlights_list.length; + + } + else + { + $curr_sel = $highlights_list[$index +1] + search_index.innerHTML = ( $index+2) + " of " + $highlights_list.length; + } + + var $target = document.querySelector("#code_explorer-file_viewer") + $target.scrollTop = 0; + $target.scrollTop =$curr_sel.offsetTop -40; ') + + } + + }) + observeEvent(input$prev_button,{ + if (input$prev_button > 0){ + + shinyjs::runjs('var $index =Array.from($highlights_list).findIndex(node => node.isEqualNode($curr_sel)); + if( $index ==0) + { + $curr_sel = $highlights_list[$highlights_list.length -1] + search_index.innerHTML = $highlights_list.length + " of " + $highlights_list.length; + } + else + { + $curr_sel = $highlights_list[$index -1] + search_index.innerHTML = ($index) + " of " + $highlights_list.length; + } + var $target = document.querySelector("#code_explorer-file_viewer") + + $target.scrollTop = 0; + $target.scrollTop = $curr_sel.offsetTop - 40; + + ') + } + + }) output$file_output <- renderUI({ switch (input$file_type, test = test_code(), diff --git a/R/mod_code_explorer_utils.R b/R/mod_code_explorer_utils.R index 9d73ceec..d2e1a2ab 100644 --- a/R/mod_code_explorer_utils.R +++ b/R/mod_code_explorer_utils.R @@ -172,9 +172,19 @@ renderCode <- function(lines, hlindex) { }) ), tags$script(HTML(" + document.querySelectorAll('.code pre').forEach(bl => { hljs.highlightBlock(bl); }); + var $highlights_list = document.querySelectorAll('.highlight') + var $curr_sel = document.querySelector('.highlight') + if(typeof($highlights_list) != 'undefined' & $curr_sel != null){ + var $target = document.querySelector('#code_explorer-file_viewer') + $target.scrollTop = 0; + $target.scrollTop = $curr_sel.offsetTop - 40; + var $index1 =Array.from($highlights_list).findIndex(node => node.isEqualNode($curr_sel)) +1; + search_index.innerHTML = $index1 + ' of ' + $highlights_list.length; + } ")) ) } diff --git a/R/mod_packageDependencies.R b/R/mod_packageDependencies.R index 78f6ed05..4145769a 100644 --- a/R/mod_packageDependencies.R +++ b/R/mod_packageDependencies.R @@ -64,7 +64,7 @@ packageDependenciesServer <- function(id, selected_pkg, user, credentials, paren req(pkgref()) tryCatch( expr = { - deep_ends <- pkgref()$dependencies[[1]] %>% dplyr::as_tibble() %>% + deep_ends <- {if(suppressWarnings(is.null(nrow(pkgref()$dependencies[[1]])) || nrow(pkgref()$dependencies[[1]]) == 0)) dplyr::tibble(package = character(0), type = character(0)) else pkgref()$dependencies[[1]] %>% dplyr::as_tibble()} %>% mutate(package = stringr::str_replace(package, "\n", " ")) %>% mutate(name = stringr::str_extract(package, "^((([[A-z]]|[.][._[A-z]])[._[A-z0-9]]*)|[.])")) @@ -94,7 +94,8 @@ packageDependenciesServer <- function(id, selected_pkg, user, credentials, paren ) tryCatch( expr = { - shrug_jests <- pkgref()$suggests[[1]] %>% dplyr::as_tibble()%>% + shrug_jests <- + {if(suppressWarnings(is.null(nrow(pkgref()$suggests[[1]])) || nrow(pkgref()$suggests[[1]]) == 0)) dplyr::tibble(package = character(0), type = character(0)) else pkgref()$suggests[[1]] %>% dplyr::as_tibble()} %>% mutate(package = stringr::str_replace(package, "\n", " ")) %>% mutate(name = stringr::str_extract(package, "^((([[A-z]]|[.][._[A-z]])[._[A-z0-9]]*)|[.])")) @@ -122,8 +123,7 @@ packageDependenciesServer <- function(id, selected_pkg, user, credentials, paren decision_id = character(0))) } ) - # this is so the dependencies is also a 0x2 tibble like suggests - if (rlang::is_empty(pkgref()$dependencies[[1]])) depends(dplyr::tibble(package = character(0), type = character(0), name = character(0))) + revdeps(pkgref()$reverse_dependencies[[1]] %>% as.vector()) diff --git a/R/utils_build_cards.R b/R/utils_build_cards.R index 48ff9ae8..f10d56f5 100644 --- a/R/utils_build_cards.R +++ b/R/utils_build_cards.R @@ -256,7 +256,6 @@ build_dep_cards <- function(data, loaded, toggled){ is_url = numeric(), type = character() ) - deps <- data %>% mutate(base = if_else(name %in% c(rownames(installed.packages(priority = "base"))), "Base", "Non-Base")) %>% diff --git a/R/utils_get_db.R b/R/utils_get_db.R index 04f957d7..3836be4e 100644 --- a/R/utils_get_db.R +++ b/R/utils_get_db.R @@ -239,6 +239,42 @@ get_metric_data <- function(pkg_name, metric_class = 'maintenance', db_name = go ) } +#' Get Dependency Pkg Versions and Scores +#' +#' +#' @param pkg_name character name of the package +#' @param verify_data a data.frame used to verify whether a pkg exists in the db +#' @param cran_pkgs a data.frame containing all available cran package names/versions +#' +#' @returns a list +#' @noRd +get_versnScore <- function(pkg_name, verify_data, cran_pkgs) { + + if (rlang::is_empty(pkg_name)) + return(list(name = character(), version = character(), score = character(), + decision_id = character(), decision = character())) + + if (pkg_name %in% verify_data$name) { #loaded2_db()$name + tmp_df <- verify_data %>% filter(name == pkg_name) %>% select(score, version, decision_id, decision) + pkg_score <- tmp_df %>% pull(score) %>% as.character + pkg_versn <- tmp_df %>% pull(version) %>% as.character + pkg_decision_id <- tmp_df %>% pull(decision_id) %>% as.character + pkg_decision <- tmp_df %>% pull(decision) %>% as.character + } else { + pkg_score <- "" + pkg_versn <- if_else(pkg_name %in% c(rownames(installed.packages(priority="base"))), "", + subset(cran_pkgs, Package == pkg_name, c("Version")) %>% as.character()) + pkg_decision_id <- "" + pkg_decision <- "" + } + + return(list(name = pkg_name, version = pkg_versn, score = pkg_score, + decision_id = pkg_decision_id, decision = pkg_decision + )) +} + + + #' The 'Get Dependencies Metrics Data' function #' #' Pull the depenencies data for a specific package id, and create @@ -277,7 +313,7 @@ get_depends_data <- function(pkg_name, deps_decision_data <- purrr::map_df(deep_ends$name, ~get_versnScore(.x, loaded2_db, repo_pkgs)) if(nrow(deps_decision_data) == 0) { deps_w_decision <- dplyr::tibble(name = character(0), version = character(0), - score = character(0), decision = character(0), decision_id = character(0)) + score = character(0), decision = character(0), decision_id = character(0)) } else { deps_w_decision <- deps_decision_data } @@ -407,40 +443,6 @@ get_assess_blob <- function(pkg_lst, db_name = golem::get_golem_options('assessm } -#' Get Dependency Pkg Versions and Scores -#' -#' -#' @param pkg_name character name of the package -#' @param verify_data a data.frame used to verify whether a pkg exists in the db -#' @param cran_pkgs a data.frame containing all available cran package names/versions -#' -#' @returns a list -#' @noRd -get_versnScore <- function(pkg_name, verify_data, cran_pkgs) { - - if (rlang::is_empty(pkg_name)) - return(list(name = character(), version = character(), score = character(), - decision_id = character(), decision = character())) - - if (pkg_name %in% verify_data$name) { #loaded2_db()$name - tmp_df <- verify_data %>% filter(name == pkg_name) %>% select(score, version, decision_id, decision) - pkg_score <- tmp_df %>% pull(score) %>% as.character - pkg_versn <- tmp_df %>% pull(version) %>% as.character - pkg_decision_id <- tmp_df %>% pull(decision_id) %>% as.character - pkg_decision <- tmp_df %>% pull(decision) %>% as.character - } else { - pkg_score <- "" - pkg_versn <- if_else(pkg_name %in% c(rownames(installed.packages(priority="base"))), "", - subset(cran_pkgs, Package == pkg_name, c("Version")) %>% as.character()) - pkg_decision_id <- "" - pkg_decision <- "" - } - - return(list(name = pkg_name, version = pkg_versn, score = pkg_score, - decision_id = pkg_decision_id, decision = pkg_decision - )) -} - ##### End of get_* functions ##### diff --git a/R/utils_insert_db.R b/R/utils_insert_db.R index 97811afa..42f9c60b 100644 --- a/R/utils_insert_db.R +++ b/R/utils_insert_db.R @@ -202,7 +202,7 @@ insert_riskmetric_to_db <- function(pkg_name, pkg_version = "", metric_value <- case_when( "pkg_metric_error" %in% class(riskmetric_assess[[metric$name]][[1]]) ~ "pkg_metric_error", - metric$name == "dependencies" ~ as.character(length(unlist(as.vector(riskmetric_assess[[metric$name]][[1]][1])))), + metric$name == "dependencies" ~ as.character(NROW(riskmetric_assess[[metric$name]][[1]])), metric$name == "reverse_dependencies" ~ as.character(length(as.vector(riskmetric_assess[[metric$name]][[1]]))), metric$is_perc == 1L ~ as.character(round(riskmetric_score[[metric$name]]*100, 2)[[1]]), TRUE ~ as.character(riskmetric_assess[[metric$name]][[1]][1:length(riskmetric_assess[[metric$name]])]) diff --git a/manifest.json b/manifest.json index 5f4fea49..2546af10 100644 --- a/manifest.json +++ b/manifest.json @@ -4367,7 +4367,7 @@ "Maintainer": "Kevin Ushey ", "Repository": "RSPM", "Date/Publication": "2024-02-29 01:10:07 UTC", - "Built": "R 4.3.3; ; 2024-06-26 14:42:15 UTC; unix" + "Built": "R 4.3.3; ; 2024-07-10 16:07:53 UTC; unix" } }, "reprex": { @@ -6175,7 +6175,7 @@ "checksum": "d74482ddef0a4941a51c077f5ea60e10" }, ".github/workflows/test-coverage.yaml": { - "checksum": "c0baef024db9ec1299aae4098e904e9c" + "checksum": "a854cdb9e1cfbcbbf5ccffdf4755606b" }, ".github/workflows/write-manifest.yaml": { "checksum": "cdfc1470af653982867daed2b99d5b97" @@ -6202,7 +6202,7 @@ "checksum": "b92bdc0d72dbb64e7cf767514486ec62" }, "data-raw/internal-data.R": { - "checksum": "33c0142c3bb1bbba56e83fa0439778e7" + "checksum": "1012b9a74fd027e081b3a81bc863358e" }, "data-raw/maintenance.csv": { "checksum": "f5bb530b482daa092e9e20f6a069f1aa" @@ -6220,7 +6220,7 @@ "checksum": "99c5575cb81828e20a7fe1d205551316" }, "DESCRIPTION": { - "checksum": "9bc40f8d2e36a15c64868dc35aa47977" + "checksum": "43f16dae5ba2122f4fd55e23f7229a40" }, "inst/app/www/css/community_metrics.css": { "checksum": "f08eb25c2ee48ac22ed63b0d18994a04" @@ -6463,13 +6463,13 @@ "checksum": "97d1232340e04c53088bc8f814133dcd" }, "NEWS.md": { - "checksum": "9fd91891f54e18c5f702df550768e91a" + "checksum": "8f1dc97771e1911ac13a12a45300a516" }, "R/app_config.R": { "checksum": "c2b61f270b86b6833f0ee39c44a1a440" }, "R/app_server.R": { - "checksum": "e2a53d90bd4289198e29bec4ff19eba7" + "checksum": "8408e324004d2991c855c03040cb2dca" }, "R/app_ui.R": { "checksum": "50d68f46171151cd36457a7154e5a7a3" @@ -6481,7 +6481,7 @@ "checksum": "23ff3c99869bd59ed973d031ee2962fd" }, "R/mod_aboutInfo.R": { - "checksum": "5240534ac7d4291a0514c01106442e6f" + "checksum": "1ccb24c4960467461139c1050aafc91e" }, "R/mod_addComment.R": { "checksum": "9a4f5a5b10f127040705dbdaa312b693" @@ -6490,10 +6490,10 @@ "checksum": "61459e71d1e62587597ac1dac2c7c650" }, "R/mod_code_explorer_utils.R": { - "checksum": "fe3bd5c1243d0ba649d070a6ecf29560" + "checksum": "2588e180a69a79b7be4e3818eb3931dc" }, "R/mod_code_explorer.R": { - "checksum": "72a36a8c4d7f15e0da013104177328b1" + "checksum": "1ec3f3aac096efff1e0c360b347e2d32" }, "R/mod_communityMetrics.R": { "checksum": "fdd39bd2a7e19b8dccc195aaec57a3d8" @@ -6532,7 +6532,7 @@ "checksum": "a894eb9114e258feb99b76cdca557cd2" }, "R/mod_packageDependencies.R": { - "checksum": "6fffb51829775826e242824f268062b6" + "checksum": "f8cee3c4845b4d3c3c2f66796af28359" }, "R/mod_pkg_explorer_utils.R": { "checksum": "b7792e08cc4a67296c9df0f452c0a72a" @@ -6562,19 +6562,19 @@ "checksum": "6c4740fd1aea22825c231eec5d8d9578" }, "R/sysdata.rda": { - "checksum": "b610fc73187b7cd23521deb9339d54cf" + "checksum": "e5835b81f48d93ee0175507abbb3186f" }, "R/utils_build_cards.R": { - "checksum": "f79316fe637bb1f4038f085621d298f5" + "checksum": "a7cfdc1f9a4ad1c2835cd22eb279d8dc" }, "R/utils_config_db.R": { "checksum": "74cf2ee5e7283483a88f08d60e3728b0" }, "R/utils_get_db.R": { - "checksum": "6e87d4d43f93b4a4b556d72b848dc3f1" + "checksum": "6c0e6fb4b3716cdd0c0d2953a1cf4393" }, "R/utils_insert_db.R": { - "checksum": "2c02e4eab4d9262ef8c8e64eb0f1b4f5" + "checksum": "5eaa94311e33014f000eb3cc5aec8282" }, "R/utils_startup.R": { "checksum": "b689ee96f0761480ac65ca22cbbb4980"