From becf5cbd6f406b3b2c293c8dd02308b9f39499c7 Mon Sep 17 00:00:00 2001 From: Nikolas Burkoff Date: Wed, 14 Dec 2022 12:00:14 +0000 Subject: [PATCH] fix for new tidyselect (#166) --- .Rprofile | 2 +- DESCRIPTION | 4 +- NEWS.md | 4 + R/caching.R | 41 ++- R/dependencies.R | 251 ++++++++------- R/dependencies_app.R | 114 +++---- R/dependencies_helper.R | 81 ++--- R/git_tools.R | 129 ++++---- R/graph_methods.R | 16 +- R/host.R | 7 +- R/ref_strategy.R | 42 ++- R/renv.R | 3 +- R/rstudio_jobs.R | 14 +- R/utils.R | 36 ++- R/zzz.R | 2 - man/build_check_install.Rd | 10 +- man/check_downstream_job.Rd | 6 +- man/dependency_table.Rd | 20 +- man/determine_ref.Rd | 28 +- man/get_all_external_dependencies.Rd | 26 +- man/install_deps.Rd | 1 - man/install_deps_app.Rd | 2 +- man/topological_sort.Rd | 10 +- renv.lock | 294 +++++++++--------- renv/.gitignore | 1 + renv/activate.R | 101 ++++-- tests/testthat/test-caching.R | 39 ++- tests/testthat/test-check_set_equal.R | 10 +- tests/testthat/test-dependencies.R | 180 ++++++----- tests/testthat/test-dependencies_helper.R | 94 +++--- .../testthat/test-get_descendants_distance.R | 54 ++-- tests/testthat/test-git_tools.R | 35 ++- tests/testthat/test-git_tools_mocking.R | 45 +-- tests/testthat/test-graph_methods.R | 2 - tests/testthat/test-ref_strategy.R | 26 +- tests/testthat/test-renv.R | 2 +- tests/testthat/test-utils.R | 18 +- tests/testthat/test-validate_yaml.R | 10 - 38 files changed, 987 insertions(+), 773 deletions(-) diff --git a/.Rprofile b/.Rprofile index 42759a3..33561f3 100644 --- a/.Rprofile +++ b/.Rprofile @@ -1,3 +1,3 @@ # source("~/.Rprofile") -#todo: uncomment +# todo: uncomment source("renv/activate.R") diff --git a/DESCRIPTION b/DESCRIPTION index ba48874..eef4f40 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: staged.dependencies Type: Package Title: Install R packages from Particular Git Branches -Version: 0.2.7 +Version: 0.2.8 Authors@R: c( person("Adrian", "Waddell", email = "adrian.waddell@roche.com", role = c("aut", "cre")), person("Maximilian", "Mordig", email = "maximilian_oliver.mordig@roche.com", role = "aut"), @@ -33,7 +33,7 @@ Description: When developing multiple dependent packages, it is often useful to License: file LICENSE Encoding: UTF-8 LazyData: true -RoxygenNote: 7.2.0 +RoxygenNote: 7.2.1 Roxygen: list(markdown = TRUE) Suggests: knitr, diff --git a/NEWS.md b/NEWS.md index df1ca81..69e4ec3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,7 @@ +# staged.dependecies 0.2.8 + +* Updated code for changes in `tidyselect 1.2.0`. + # staged.dependencies 0.2.7 * Fixed a bug whereby the cache file for packages with compiled code was not reset after installation thereby `dependency_table` failed on a 2nd run. diff --git a/R/caching.R b/R/caching.R index bcd2e34..a607067 100644 --- a/R/caching.R +++ b/R/caching.R @@ -121,24 +121,30 @@ copy_local_repo_to_cachedir <- function(local_dir, repo, host, select_ref_rule, if (ref != get_current_branch(repo_dir)) { # if ref is a branch and you are on the wrong branch throw error if (attr(ref, "type") == "branch") { - stop("You must check out branch ", ref, " for repository in directory ", repo_dir, - ", currently ", get_current_branch(repo_dir), " is checked out.") + stop( + "You must check out branch ", ref, " for repository in directory ", repo_dir, + ", currently ", get_current_branch(repo_dir), " is checked out." + ) } # if ref is a tag, just throw warning as may want to work from elsewhere here else { - warning("You should check out a branch from tag ", ref, " for repository in directory ", repo_dir, - ", currently branch ", get_current_branch(repo_dir), " is checked out.") + warning( + "You should check out a branch from tag ", ref, " for repository in directory ", repo_dir, + ", currently branch ", get_current_branch(repo_dir), " is checked out." + ) } } } if ((length(git2r::status(repo_dir)$staged) > 0) || - (length(git2r::status(repo_dir)$unstaged) > 0) || - (length(git2r::status(repo_dir)$untracked) > 0)) { + (length(git2r::status(repo_dir)$unstaged) > 0) || + (length(git2r::status(repo_dir)$untracked) > 0)) { # add all files, including untracked (all argument of git2r::commit does not do this) if (verbose >= 2) { - message("Adding all of the following files: \n", - paste(utils::capture.output(git2r::status(repo_dir)), collapse = "\n")) + message( + "Adding all of the following files: \n", + paste(utils::capture.output(git2r::status(repo_dir)), collapse = "\n") + ) } git2r::add(repo_dir, ".") git2r::commit( @@ -147,8 +153,10 @@ copy_local_repo_to_cachedir <- function(local_dir, repo, host, select_ref_rule, ) } - return(list(dir = repo_dir, ref = paste0("local (", current_branch, ")"), - sha = get_short_sha(repo_dir), accessible = TRUE)) + return(list( + dir = repo_dir, ref = paste0("local (", current_branch, ")"), + sha = get_short_sha(repo_dir), accessible = TRUE + )) } @@ -158,7 +166,8 @@ copy_renv_profiles <- function(renv_directory, repo_dir) { renv_sub_directories <- fs::dir_ls(renv_directory, type = "directory", all = TRUE) if ("profiles" %in% fs::path_file(renv_sub_directories)) { renv_profiles <- fs::dir_ls(fs::path_join(c(renv_directory, "profiles")), - type = "directory", all = TRUE) + type = "directory", all = TRUE + ) lapply(renv_profiles, function(x) { fs::dir_create(fs::path_join(c(repo_dir, "renv", "profiles", fs::path_file(x))), recurse = TRUE) if (fs::file_exists(fs::path_join(c(x, "renv.lock")))) { @@ -212,10 +221,10 @@ get_hashed_repo_to_dir_mapping <- function(local_repos) { #' @return A data frame, one row per checked out repository with columns #' repo, host and cache_dir rec_checkout_internal_deps <- function(repos_to_process, ref, - direction = "upstream", - local_repos = get_local_pkgs_from_config(), - fallback_branch = "main", - verbose = 0) { + direction = "upstream", + local_repos = get_local_pkgs_from_config(), + fallback_branch = "main", + verbose = 0) { stopifnot( is.list(repos_to_process) ) @@ -257,7 +266,7 @@ rec_checkout_internal_deps <- function(repos_to_process, ref, get_repo_url(repo_and_host$repo, repo_and_host$host), token_envvar = get_authtoken_envvar(repo_and_host$host), select_ref_rule = function(available_refs) { - determine_ref(ref, available_refs, fallback_branch = fallback_branch) + determine_ref(ref, available_refs, fallback_branch = fallback_branch) }, must_work = (length(hashed_processed_repos) == 0), # first repo must be accessible verbose = verbose diff --git a/R/dependencies.R b/R/dependencies.R index 7fd77b6..e8909fc 100644 --- a/R/dependencies.R +++ b/R/dependencies.R @@ -53,14 +53,18 @@ #' @export #' @examples #' \dontrun{ -#' dependency_table(verbose = 1) -#' dependency_table(project = "openpharma/stageddeps.food@https://github.com", -#' project_type = "repo@@host", -#' ref = "main") -#' x <- dependency_table(project = "path/to/project", -#' direction = c("upstream")) -#' print(x) -#' plot(x) +#' dependency_table(verbose = 1) +#' dependency_table( +#' project = "openpharma/stageddeps.food@https://github.com", +#' project_type = "repo@@host", +#' ref = "main" +#' ) +#' x <- dependency_table( +#' project = "path/to/project", +#' direction = c("upstream") +#' ) +#' print(x) +#' plot(x) #' } dependency_table <- function(project = ".", project_type = c("local", "repo@host")[1], @@ -89,15 +93,16 @@ dependency_table <- function(project = ".", if (is.null(ref) || nchar(ref) == 0) { ref <- infer_ref_from_branch(project) } - } if (project_type == "local") { # take local version of project (rather than remote) local_repos <- add_project_to_local_repos(project, local_repos) repo_deps_info <- get_yaml_deps_info(project) - check_ref_consistency(ref, project, - get_remote_name(project, + check_ref_consistency( + ref, project, + get_remote_name( + project, get_repo_url(repo_deps_info[["current_repo"]]$repo, repo_deps_info[["current_repo"]]$host) ), fallback_branch @@ -110,7 +115,8 @@ dependency_table <- function(project = ".", # a dataframe with columns repo, host, ref, sha, cache_dir, accessible (logical) internal_deps <- rec_checkout_internal_deps( - repo_to_process, ref, direction = direction, + repo_to_process, ref, + direction = direction, local_repos = local_repos, fallback_branch = fallback_branch, verbose = verbose ) @@ -137,7 +143,7 @@ dependency_table <- function(project = ".", current_pkg <- internal_deps$package_name[ internal_deps$repo == repo_to_process[[1]]$repo & internal_deps$host == repo_to_process[[1]]$host - ] + ] internal_deps$type[internal_deps$package_name == current_pkg] <- "current" internal_deps$distance[internal_deps$package_name == current_pkg] <- 0 @@ -158,7 +164,8 @@ dependency_table <- function(project = ".", uninstallable_packages <- unique( unlist( - lapply(internal_deps$package_name[!internal_deps$accessible], + lapply( + internal_deps$package_name[!internal_deps$accessible], function(pkg) get_descendants_distance(deps[["downstream_deps"]], pkg)$id ) ) @@ -168,16 +175,21 @@ dependency_table <- function(project = ".", # sort the table - internal_deps <- internal_deps[order(internal_deps$type, internal_deps$distance), - c("package_name", "type", "distance", "ref", - "repo", "host", "sha", "cache_dir", "accessible", "installable")] + internal_deps <- internal_deps[ + order(internal_deps$type, internal_deps$distance), + c( + "package_name", "type", "distance", "ref", + "repo", "host", "sha", "cache_dir", "accessible", "installable" + ) + ] rownames(internal_deps) <- NULL # install_index: order in which to install packages internal_deps$install_index <- vapply(internal_deps$package_name, - function(y) which(names(deps[["upstream_deps"]]) == y), - FUN.VALUE = numeric(1)) + function(y) which(names(deps[["upstream_deps"]]) == y), + FUN.VALUE = numeric(1) + ) renv_files <- lapply(internal_deps$cache_dir, get_renv_lock_from_repo_dir, renv_profile = renv_profile) names(renv_files) <- internal_deps$package_name @@ -199,7 +211,6 @@ dependency_table <- function(project = ".", #' @export print.dependency_structure <- function(x, ...) { - table <- x$table # do not show the cache dir or install order when printing table$cache_dir <- NULL @@ -207,35 +218,38 @@ print.dependency_structure <- function(x, ...) { if (!all(table$installable)) { table$package_name <- paste0(table$package_name, ifelse(table$installable, "", "*")) - cat("packages denoted with '*' cannot be installed as either they or one of their internal", - "dependencies is not accessible\n") + cat( + "packages denoted with '*' cannot be installed as either they or one of their internal", + "dependencies is not accessible\n" + ) } table$accessible <- NULL table$installable <- NULL print(table, ...) - } #' @importFrom dplyr %>% #' @importFrom rlang .data #' @export -plot.dependency_structure <- function(x, y, ...){ +plot.dependency_structure <- function(x, y, ...) { # construct visNetwork graph require_pkgs("visNetwork") # todo: put branch below node: https://github.com/almende/vis/issues/3436 - nodes <- x$table %>% dplyr::mutate( - id = .data$package_name, - # label does not support html tags - label = paste0(.data$package_name, "\n", .data$ref), - title = paste0("

", .data$package_name, "
", .data$type, "
", .data$ref, "

"), - value = 3, - group = .data$type, - shape = ifelse(.data$installable, "dot", "square") - ) %>% dplyr::select(c("id", "label", "title", "value", "group", "shape")) + nodes <- x$table %>% + dplyr::mutate( + id = .data$package_name, + # label does not support html tags + label = paste0(.data$package_name, "\n", .data$ref), + title = paste0("

", .data$package_name, "
", .data$type, "
", .data$ref, "

"), + value = 3, + group = .data$type, + shape = ifelse(.data$installable, "dot", "square") + ) %>% + dplyr::select(c("id", "label", "title", "value", "group", "shape")) edges <- rbind( cbind_handle_empty( @@ -243,7 +257,7 @@ plot.dependency_structure <- function(x, y, ...){ arrows = "to", listed_by = "from" ), cbind_handle_empty( - adj_list_to_edge_df(x$deps[["downstream_deps"]]) %>% dplyr::rename(to = .data$from, from = .data$to), + adj_list_to_edge_df(x$deps[["downstream_deps"]]) %>% dplyr::rename(to = "from", from = "to"), arrows = "to", listed_by = "to" ) ) @@ -272,7 +286,8 @@ plot.dependency_structure <- function(x, y, ...){ stop("Unexpected listed_by: ", listed_by) } } - edges <- edges %>% dplyr::group_by(.data$from, .data$to) %>% + edges <- edges %>% + dplyr::group_by(.data$from, .data$to) %>% dplyr::mutate(color = get_edge_color(.data$listed_by)) %>% dplyr::mutate(title = get_edge_tooltip(.data$from, .data$to, .data$listed_by)) %>% dplyr::mutate(dashes = !setequal(.data$listed_by, c("from", "to"))) %>% @@ -351,7 +366,6 @@ plot.dependency_structure <- function(x, y, ...){ #' #' # install all dependencies #' install_deps(x, install_direction = "all") -#' #' } install_deps <- function(dep_structure, install_project = TRUE, @@ -362,7 +376,6 @@ install_deps <- function(dep_structure, dry = FALSE, verbose = 1, ...) { - stopifnot(methods::is(dep_structure, "dependency_structure")) stopifnot(is.logical(install_project), is.logical(dry)) @@ -375,8 +388,9 @@ install_deps <- function(dep_structure, pkg_df <- dep_structure$table pkg_names <- filter_pkgs(pkg_df, install_direction, - include_project = install_project, - package_list = package_list) + include_project = install_project, + package_list = package_list + ) # we also need to install the upstream dependencies of e.g. the downstream dependencies @@ -385,11 +399,13 @@ install_deps <- function(dep_structure, pkg_actions <- compute_actions(pkg_df, pkg_names, "install", upstream_pkgs) - run_package_actions(pkg_actions, dry = dry, - install_external_deps = install_external_deps, - upgrade = upgrade, - internal_pkg_deps = dep_structure$table$package_name, - verbose = verbose, ...) + run_package_actions(pkg_actions, + dry = dry, + install_external_deps = install_external_deps, + upgrade = upgrade, + internal_pkg_deps = dep_structure$table$package_name, + verbose = verbose, ... + ) pkg_actions } @@ -436,10 +452,12 @@ check_downstream <- function(dep_structure, # get the packages to install pkg_df <- dep_structure$table - pkg_names <- filter_pkgs(pkg_df, install_direction = "downstream", - include_project = FALSE, - package_list = package_list, - distance = distance) + pkg_names <- filter_pkgs(pkg_df, + install_direction = "downstream", + include_project = FALSE, + package_list = package_list, + distance = distance + ) # we also need to install the upstream dependencies of e.g. the downstream dependencies @@ -449,12 +467,14 @@ check_downstream <- function(dep_structure, actions <- if (only_tests) c("test", "install") else c("check", "install") pkg_actions <- compute_actions(pkg_df, pkg_names, actions, upstream_pkgs) - run_package_actions(pkg_actions, dry = dry, - install_external_deps = install_external_deps, - upgrade = upgrade, - internal_pkg_deps = dep_structure$table$package_name, - rcmd_args = list(check = check_args), - verbose = verbose, ...) + run_package_actions(pkg_actions, + dry = dry, + install_external_deps = install_external_deps, + upgrade = upgrade, + internal_pkg_deps = dep_structure$table$package_name, + rcmd_args = list(check = check_args), + verbose = verbose, ... + ) pkg_actions } @@ -478,9 +498,11 @@ update_with_direct_deps <- function(dep_structure) { yaml_contents <- yaml_from_dep_table(dep_structure$table) yaml::write_yaml( - list(current_repo = yaml_contents$current_repo, - upstream_repos = yaml_contents$upstream_repos, - downstream_repos = yaml_contents$downstream_repos), + list( + current_repo = yaml_contents$current_repo, + upstream_repos = yaml_contents$upstream_repos, + downstream_repos = yaml_contents$downstream_repos + ), file = file.path(dep_structure$project, STAGEDDEPS_FILENAME) ) } @@ -505,22 +527,20 @@ update_with_direct_deps <- function(dep_structure) { #' @export #' @examples #' \dontrun{ -#' x <- dependency_table(project = ".", verbose = 1) -#' build_check_install(x, steps = c("build", "check"), verbose = 1) -#' build_check_install(x, artifact_dir = "../output") -#' +#' x <- dependency_table(project = ".", verbose = 1) +#' build_check_install(x, steps = c("build", "check"), verbose = 1) +#' build_check_install(x, artifact_dir = "../output") #' } build_check_install <- function(dep_structure, - install_direction = "all", - steps = c("build", "check", "install"), - rcmd_args = list(check = c("--no-multiarch", "--with-keep.source", "--install-tests")), - artifact_dir = tempfile(), - install_external_deps = TRUE, - upgrade = "never", - package_list = NULL, - dry = FALSE, verbose = 1, - ...) { - + install_direction = "all", + steps = c("build", "check", "install"), + rcmd_args = list(check = c("--no-multiarch", "--with-keep.source", "--install-tests")), + artifact_dir = tempfile(), + install_external_deps = TRUE, + upgrade = "never", + package_list = NULL, + dry = FALSE, verbose = 1, + ...) { steps <- match.arg(steps, several.ok = TRUE) stopifnot( methods::is(dep_structure, "dependency_structure"), @@ -539,9 +559,11 @@ build_check_install <- function(dep_structure, # get the packages to install pkg_df <- dep_structure$table - pkg_names <- filter_pkgs(pkg_df, install_direction = install_direction, - include_project = TRUE, - package_list = package_list) + pkg_names <- filter_pkgs(pkg_df, + install_direction = install_direction, + include_project = TRUE, + package_list = package_list + ) # we also need to install the upstream dependencies of e.g. the downstream dependencies @@ -550,13 +572,15 @@ build_check_install <- function(dep_structure, pkg_actions <- compute_actions(pkg_df, pkg_names, steps, upstream_pkgs) - run_package_actions(pkg_actions, dry = dry, - install_external_deps = install_external_deps, - upgrade = upgrade, - internal_pkg_deps = dep_structure$table$package_name, - rcmd_args = rcmd_args, - artifact_dir = artifact_dir, - verbose = verbose, ...) + run_package_actions(pkg_actions, + dry = dry, + install_external_deps = install_external_deps, + upgrade = upgrade, + internal_pkg_deps = dep_structure$table$package_name, + rcmd_args = rcmd_args, + artifact_dir = artifact_dir, + verbose = verbose, ... + ) return(list(artifact_dir = artifact_dir, pkg_actions = pkg_actions)) } @@ -582,7 +606,6 @@ build_check_install <- function(dep_structure, #' check_yamls_consistent(x) #' } check_yamls_consistent <- function(dep_structure, skip_if_missing_yaml = FALSE) { - stopifnot(methods::is(dep_structure, "dependency_structure")) stopifnot(dep_structure$direction == "all") stopifnot(rlang::is_bool(skip_if_missing_yaml)) @@ -610,7 +633,8 @@ check_yamls_consistent <- function(dep_structure, skip_if_missing_yaml = FALSE) # check that packages upstream in the yaml file are upstream deps upstream_packages_in_yaml <- vapply(yaml_deps$upstream_repos, extract_package_name, dep_structure$table, - FUN.VALUE = character(1)) + FUN.VALUE = character(1) + ) upstream_packages_in_desc <- dep_structure$deps[["upstream_deps"]][[package_name]] # the dep_structure$deps only lists the internal package error_msg <- c(error_msg, check_set_equal( @@ -620,7 +644,8 @@ check_yamls_consistent <- function(dep_structure, skip_if_missing_yaml = FALSE) )) downstream_packages_in_yaml <- vapply(yaml_deps$downstream_repos, extract_package_name, dep_structure$table, - FUN.VALUE = character(1)) + FUN.VALUE = character(1) + ) downstream_packages_in_desc <- dep_structure$deps[["downstream_deps"]][[package_name]] error_msg <- c(error_msg, check_set_equal( downstream_packages_in_yaml, downstream_packages_in_desc, @@ -659,20 +684,22 @@ check_yamls_consistent <- function(dep_structure, skip_if_missing_yaml = FALSE) #' to extract the system requirements needed for your packages, see example below. #' @examples #' \dontrun{ -#' x <- dependency_table("openpharma/stageddeps.electricity", -#' project_type = "repo@host", feature = "main") +#' x <- dependency_table("openpharma/stageddeps.electricity", +#' project_type = "repo@host", feature = "main" +#' ) #' -#' # get external package dependencies -#' ex_deps <- get_all_external_dependencies(x) -#' print(ex_deps) +#' # get external package dependencies +#' ex_deps <- get_all_external_dependencies(x) +#' print(ex_deps) #' -#' # get system dependencies (in this case there are none) -#' unique(unlist(lapply(ex_deps, -#' function(pkg, ...) -#' remotes::system_requirements(package = pkg, ...), -#' os = "ubuntu", -#' os_release = "20.04") -#' )) +#' # get system dependencies (in this case there are none) +#' unique(unlist(lapply(ex_deps, +#' function(pkg, ...) { +#' remotes::system_requirements(package = pkg, ...) +#' }, +#' os = "ubuntu", +#' os_release = "20.04" +#' ))) #' } #' @export get_all_external_dependencies <- function(dep_structure, @@ -695,15 +722,19 @@ get_all_external_dependencies <- function(dep_structure, stop("Invalid install_direction argument for this dependency object") } - r_core_packages <- c("base", "compiler", "datasets", "graphics", "grDevices", "grid", - "methods", "parallel", "splines", "stats", "stats4", "tcltk", "tools", "translations", "utils") + r_core_packages <- c( + "base", "compiler", "datasets", "graphics", "grDevices", "grid", + "methods", "parallel", "splines", "stats", "stats4", "tcltk", "tools", "translations", "utils" + ) # get the packages to consider pkg_df <- dep_structure$table - pkg_names <- filter_pkgs(pkg_df, install_direction = install_direction, - include_project = TRUE, - package_list = package_list) + pkg_names <- filter_pkgs(pkg_df, + install_direction = install_direction, + include_project = TRUE, + package_list = package_list + ) # we also need to consider the upstream dependencies of e.g. the downstream dependencies @@ -717,17 +748,19 @@ get_all_external_dependencies <- function(dep_structure, external_packages <- character(0) # and those to consider packages_to_consider <- unique(unlist( - lapply(dep_structure$deps$external[names(dep_structure$deps$external) %in% c(upstream_pkgs, pkg_names)], - function(df) df$package[df$type %in% from_internal_dependencies]) + lapply( + dep_structure$deps$external[names(dep_structure$deps$external) %in% c(upstream_pkgs, pkg_names)], + function(df) df$package[df$type %in% from_internal_dependencies] ) - ) + )) while (length(packages_to_consider) > 0) { - if (any(!packages_to_consider %in% c(available_packages$Package, r_core_packages))) { - warning("Cannot find information about package(s) ", + warning( + "Cannot find information about package(s) ", toString(packages_to_consider[!packages_to_consider %in% c(available_packages$Package, r_core_packages)]), - " check that options('repos') contains expected repos") + " check that options('repos') contains expected repos" + ) } # get appropriate rows of data.frame @@ -754,9 +787,9 @@ get_all_external_dependencies <- function(dep_structure, } else { external_package_table <- available_packages[available_packages$Package %in% external_packages, ] - package_deps <- apply(external_package_table, 1, function(row) + package_deps <- apply(external_package_table, 1, function(row) { unique(unlist(lapply(c("Depends", "Imports", "LinkingTo"), function(x) parse_deps_table(row[x])))) - ) + }) names(package_deps) <- external_package_table$Package ordered_external_packages <- topological_sort(package_deps) diff --git a/R/dependencies_app.R b/R/dependencies_app.R index 9dbcf0d..c97c8c1 100644 --- a/R/dependencies_app.R +++ b/R/dependencies_app.R @@ -25,7 +25,7 @@ #' @return `shiny.app` or value returned by app (executed as a gadget) #' @examples #' \dontrun{ -#' install_deps_app("openpharma/stageddeps.food") +#' install_deps_app("openpharma/stageddeps.food") #' } install_deps_app <- function(default_repo = NULL, default_host = "https://github.com", @@ -72,41 +72,45 @@ install_deps_app <- function(default_repo = NULL, ) }, server = function(input, output, session) { - dep_table_rv <- shiny::reactiveVal() error_rv <- shiny::reactiveVal() - shiny::observeEvent(input$compute_graph, { + shiny::observeEvent(input$compute_graph, + { + dep_table_rv(NULL) + error_rv(NULL) - dep_table_rv(NULL) - error_rv(NULL) + message_if_verbose("Computing dependency structure for ref ", + input$ref, " starting from project ", paste(input$repo, input$host, sep = "@"), + verbose = verbose + ) - message_if_verbose("Computing dependency structure for ref ", - input$ref, " starting from project ", paste(input$repo, input$host, sep = "@"), - verbose = verbose) + x <- tryCatch( + { + if (is.null(input$ref) || input$ref == "" || is.null(input$repo) || input$repo == "" || + is.null(input$host) || input$host == "") { + stop("Please enter a repo, host and ref and \nthen press 'Compute graph'") + } + dependency_table( + project = paste(input$repo, input$host, sep = "@"), + project_type = "repo@host", ref = input$ref, fallback_branch = fallback_branch, + local_repos = NULL, renv_profile = renv_profile, verbose = 2 + ) + }, + error = function(cond) { + error_rv(paste0("Cannot create dependency graph:\n", cond$message)) + NULL + } + ) - x <- tryCatch({ - if(is.null(input$ref) || input$ref == "" || is.null(input$repo) || input$repo == "" || - is.null(input$host) || input$host == "") { - stop("Please enter a repo, host and ref and \nthen press 'Compute graph'") - } - dependency_table(project = paste(input$repo, input$host, sep = "@"), - project_type = "repo@host", ref = input$ref, fallback_branch = fallback_branch, - local_repos = NULL, renv_profile = renv_profile, verbose = 2)}, - error = function(cond){ - error_rv(paste0("Cannot create dependency graph:\n", cond$message)) - NULL + if (!is.null(x)) { + dep_table_rv(x) } - ) - - if (!is.null(x)) { - dep_table_rv(x) - } - - }, - # do not ignore NULL to also compute initially with the default feature when - # the button was not yet clicked - ignoreNULL = FALSE) + }, + # do not ignore NULL to also compute initially with the default feature when + # the button was not yet clicked + ignoreNULL = FALSE + ) output$error_output <- shiny::renderText({ shiny::req(error_rv()) @@ -123,12 +127,15 @@ install_deps_app <- function(default_repo = NULL, # todo: better solution? this only updates every 1s, so clicking on # okay in between takes old selected nodes autoInvalidate <- shiny::reactiveTimer(1000) - shiny::observeEvent({ - autoInvalidate() - }, { - visNetwork::visNetworkProxy("network_proxy_nodes") %>% - visNetwork::visGetSelectedNodes() - }) + shiny::observeEvent( + { + autoInvalidate() + }, + { + visNetwork::visNetworkProxy("network_proxy_nodes") %>% + visNetwork::visGetSelectedNodes() + } + ) output$nodesToInstall <- shiny::renderText({ shiny::req(dep_table_rv()) @@ -138,10 +145,7 @@ install_deps_app <- function(default_repo = NULL, ), collapse = "\n") }) shiny::observeEvent(input$done, { - if (!is.null(dep_table_rv())) { - - dependency_packages <- setdiff( dep_table_rv()$table$package_name[dep_table_rv()$table$installable], input$network_proxy_nodes_selectedNodes @@ -153,21 +157,24 @@ install_deps_app <- function(default_repo = NULL, # recreate the dep_structure object (which should be a fraction of the install time) # this could be changed by using the importEnv argument # to jobRunScript and creating an install_deps job if dep_structure already exists in env - install_deps_job(project = paste(input$repo, input$host, sep = "@"), project_type = "repo@host", verbose = verbose, - create_args = list(local_repos = NULL, ref = input$ref, renv_profile = renv_profile), - dependency_packages = dependency_packages, fallback_branch = fallback_branch, - install_external_deps = install_external_deps, - install_direction = "all", - upgrade = upgrade, - ...) - } else{ + install_deps_job( + project = paste(input$repo, input$host, sep = "@"), project_type = "repo@host", verbose = verbose, + create_args = list(local_repos = NULL, ref = input$ref, renv_profile = renv_profile), + dependency_packages = dependency_packages, fallback_branch = fallback_branch, + install_external_deps = install_external_deps, + install_direction = "all", + upgrade = upgrade, + ... + ) + } else { install_deps(dep_table_rv(), - dependency_packages = dependency_packages, - verbose = verbose, - install_external_deps = install_external_deps, - install_direction = "all", - upgrade = upgrade, - ...) + dependency_packages = dependency_packages, + verbose = verbose, + install_external_deps = install_external_deps, + install_direction = "all", + upgrade = upgrade, + ... + ) } @@ -177,7 +184,8 @@ install_deps_app <- function(default_repo = NULL, } }) } - ); app + ) + app if (run_gadget) { shiny::runGadget(app, viewer = shiny::dialogViewer("Install packages")) # shiny::runGadget(app, viewer = browserViewer()) diff --git a/R/dependencies_helper.R b/R/dependencies_helper.R index c8f4fff..9a79280 100644 --- a/R/dependencies_helper.R +++ b/R/dependencies_helper.R @@ -32,7 +32,6 @@ run_package_actions <- function(pkg_actions, internal_pkg_deps, rcmd_args = NULL, artifact_dir = NULL, verbose = 0, ...) { - all_actions <- unique(unlist(pkg_actions$actions)) stopifnot(all(all_actions %in% c("test", "build", "check", "install"))) check_verbose_arg(verbose) @@ -44,12 +43,12 @@ run_package_actions <- function(pkg_actions, internal_pkg_deps, return(pkg_actions) } - if ("build" %in% all_actions && is.null( artifact_dir)) { + if ("build" %in% all_actions && is.null(artifact_dir)) { stop("when building a package an artifact_dir must be specified") } if (!is.null(artifact_dir)) { - #TODO empty directories if exist? + # TODO empty directories if exist? lapply( intersect(all_actions, c("build", "install")), function(action) fs::dir_create(file.path(artifact_dir, paste0(action, "_logs"))) @@ -57,17 +56,19 @@ run_package_actions <- function(pkg_actions, internal_pkg_deps, } message_if_verbose("Processing packages in order: ", - toString(pkg_actions$package_name), - verbose = verbose) + toString(pkg_actions$package_name), + verbose = verbose + ) for (idx in seq_along(pkg_actions$cache_dir)) { - cache_dir <- pkg_actions$cache_dir[idx] actions <- pkg_actions$actions[idx] if (!pkg_actions$installable[idx]) { message_if_verbose("skipping package ", pkg_actions$package_name[idx], - " as it (or one of its upstream dependencies) is not accessible", verbose = verbose) + " as it (or one of its upstream dependencies) is not accessible", + verbose = verbose + ) next } @@ -76,12 +77,13 @@ run_package_actions <- function(pkg_actions, internal_pkg_deps, sha <- pkg_actions$sha[idx] cached_sha <- get_short_sha(cache_dir) if (sha != cached_sha) { - stop("The SHA in ", cache_dir, ": ", cached_sha, - " does not match the sha in the dependency_structure object: ", sha) + stop( + "The SHA in ", cache_dir, ": ", cached_sha, + " does not match the sha in the dependency_structure object: ", sha + ) } if (!dry) { - if ("test" %in% actions[[1]]) { # testthat::test_dir and devtools::test do not always agree # testthat::test_dir(file.path(repo_dir, "tests"), stop_on_failure = TRUE, stop_on_warning = TRUE) @@ -111,7 +113,8 @@ run_package_actions <- function(pkg_actions, internal_pkg_deps, withr::with_dir(artifact_dir, { pkg_name <- desc::desc_get_field("Package", file = cache_dir) system2( - "R", args = c("CMD", "build", rcmd_args$build, cache_dir), + "R", + args = c("CMD", "build", rcmd_args$build, cache_dir), stdout = file.path("build_logs", paste0(pkg_name, "_stdout.txt")), stderr = file.path("build_logs", paste0(pkg_name, "_stderr.txt")) ) @@ -134,34 +137,37 @@ run_package_actions <- function(pkg_actions, internal_pkg_deps, if ("install" %in% actions[[1]]) { if (install_external_deps) { - install_external_deps(cache_dir, internal_pkg_deps = internal_pkg_deps, - dependencies = TRUE, upgrade = upgrade, ...) + install_external_deps(cache_dir, + internal_pkg_deps = internal_pkg_deps, + dependencies = TRUE, upgrade = upgrade, ... + ) } # install the tar.gz if it exists otherwise install using staged.deps if (!is.null(package_tar)) { withr::with_dir( artifact_dir, - system2("R", args = c("CMD", "INSTALL", rcmd_args$install, package_tar), - stdout = file.path("install_logs", paste0(pkg_name, "_stdout.txt")), - stderr = file.path("install_logs", paste0(pkg_name, "_stderr.txt"))) + system2("R", + args = c("CMD", "INSTALL", rcmd_args$install, package_tar), + stdout = file.path("install_logs", paste0(pkg_name, "_stdout.txt")), + stderr = file.path("install_logs", paste0(pkg_name, "_stderr.txt")) + ) ) } else { install_repo_add_sha(cache_dir, ...) } } - } else { # dry run message_if_verbose(cat_nl("(Dry run) Skipping", toString(actions), "of", cache_dir), verbose = verbose) } - } message_if_verbose("Processed packages in order: ", toString(pkg_actions$package_name), verbose = verbose) # output rcmdcheck outputs if (!rlang::is_empty(rcmdcheck_outputs)) { - lapply(names(rcmdcheck_outputs), + lapply( + names(rcmdcheck_outputs), function(pkg_name) { print(paste("R CMD CHECK package ", pkg_name)) print(rcmdcheck_outputs[[pkg_name]]) @@ -207,8 +213,9 @@ get_local_pkgs_from_config <- function() { if (file.exists(filename)) { content <- yaml::read_yaml(filename) local_pkgs <- content[["local_packages"]] - df <- do.call(rbind, - lapply(local_pkgs, function(x) data.frame(x, stringsAsFactors = FALSE)) + df <- do.call( + rbind, + lapply(local_pkgs, function(x) data.frame(x, stringsAsFactors = FALSE)) ) if (is.null(df)) { return(NULL) @@ -240,7 +247,6 @@ get_local_pkgs_from_config <- function() { # idocument where the names are the dependency type (e.g. Imports, Suggests,...) get_true_deps_graph <- function(pkgs_df, graph_directions = "upstream") { - stopifnot( is.data.frame(pkgs_df), all(c("package_name", "cache_dir") %in% colnames(pkgs_df)) @@ -251,7 +257,8 @@ get_true_deps_graph <- function(pkgs_df, # get the Imports, Suggests, Depends for each package # from the package DESCRIPTION files, filter for only # the internal packages - upstream_deps <- lapply(pkgs_df$cache_dir, + upstream_deps <- lapply( + pkgs_df$cache_dir, function(file) { if (is.na(file)) { return(character(0)) @@ -278,25 +285,27 @@ get_true_deps_graph <- function(pkgs_df, # check if repo and host match for any inaccessible package for (downstream_dep in downstream_deps) { - inaccessible_deps <- dplyr::filter(pkgs_df, .data$repo == downstream_dep$repo, - .data$host == downstream_dep$host, !.data$accessible) + inaccessible_deps <- dplyr::filter( + pkgs_df, .data$repo == downstream_dep$repo, + .data$host == downstream_dep$host, !.data$accessible + ) for (package_name in inaccessible_deps$package_name) { upstream_deps[[package_name]] <- c(upstream_deps[[package_name]], current_package_name) } } - } } - external <- lapply(pkgs_df$cache_dir, + external <- lapply( + pkgs_df$cache_dir, function(file) { if (is.na(file)) { return(data.frame(type = character(0), package = character(0), version = character(0))) } df <- desc::desc_get_deps(file) - df <- df[!df$package %in% c("R",pkgs_df$package_name), ] + df <- df[!df$package %in% c("R", pkgs_df$package_name), ] rownames(df) <- NULL df } @@ -325,7 +334,6 @@ get_true_deps_graph <- function(pkgs_df, } res - } # dep_table: dependency table as returned by `dependency_table` @@ -336,8 +344,8 @@ yaml_from_dep_table <- function(dep_table) { downstream_repos <- dep_table[dep_table$type == "downstream" & dep_table$distance == 1, c("repo", "host")] list( current_repo = list( - repo = dep_table[dep_table$type == "current",]$repo, - host = dep_table[dep_table$type == "current",]$host + repo = dep_table[dep_table$type == "current", ]$repo, + host = dep_table[dep_table$type == "current", ]$host ), upstream_repos = Map( function(repo, host) list(repo = repo, host = host), @@ -356,7 +364,7 @@ yaml_from_dep_table <- function(dep_table) { # host = "https://github.com" parse_remote_project <- function(project) { error_message <- "Invalid project argument, should be 'repo@host'" - if(nchar(trimws(project)) == 0) { + if (nchar(trimws(project)) == 0) { stop(error_message) } split_string <- strsplit(project, "@")[[1]] @@ -417,8 +425,9 @@ compute_actions <- function(pkg_df, pkg_names, actions, upstream_pkgs) { rep(list(actions), times = sum(pkg_df$package_name %in% pkg_names)) ) # outer list() to assign list elements to column pkg_df[pkg_df$package_name %in% upstream_pkgs, "actions"] <- "install" - pkg_df %>% dplyr::arrange(.data$install_index) %>% - dplyr::select(.data$package_name, .data$cache_dir, .data$actions, .data$sha, .data$installable) + pkg_df %>% + dplyr::arrange(.data$install_index) %>% + dplyr::select("package_name", "cache_dir", "actions", "sha", "installable") } @@ -430,8 +439,8 @@ parse_deps_table <- function(str) { } # remove whitespace str <- gsub("\\s", "", str) - #split by "," and remove version info within brackets - deps <- gsub("\\s*\\([^\\)]+\\)","",strsplit(str, ",")[[1]]) + # split by "," and remove version info within brackets + deps <- gsub("\\s*\\([^\\)]+\\)", "", strsplit(str, ",")[[1]]) # remove R deps <- deps[deps != "R"] return(deps) diff --git a/R/git_tools.R b/R/git_tools.R index 0413128..b93686b 100644 --- a/R/git_tools.R +++ b/R/git_tools.R @@ -55,49 +55,53 @@ checkout_repo <- function(repo_dir, repo_url, select_ref_rule, token_envvar = NU message(paste("clone", repo_url, "to directory", repo_dir)) } - cloned_repo <- tryCatch({ - git_repo <- git2r::clone( - url = repo_url, local_path = repo_dir, - credentials = creds, progress = verbose >= 2 - ) - }, error = function(e) { - # catch some common errors - # only do this when cloning because the API calls introduce quite some time overhead - host <- paste(utils::head(strsplit(repo_url, "/", fixed = TRUE)[[1]], -2), collapse = "/") - repo <- paste(utils::tail(strsplit(repo_url, "/", fixed = TRUE)[[1]], 2), collapse = "/") - repo <- substr(repo, start = 0, stop = nchar(repo) - nchar(".git")) - - if (!identical(httr::status_code(httr::HEAD(host)), 200L)) { - stop("Host ", host, " not reachable") - } - - notification_function <- if (must_work) stop else warning - - resp <- get_repo_access(repo, host, token_envvar) - if (!is.null(resp) && httr::status_code(resp) > 200) { - notification_function( - paste0("You cannot access ", repo, " at host ", host, - ". If you expect to be able to access this repo then ", - "check that repo and token in envvar '", token_envvar, - "' are correct.\n", - "The response's content was:\n", paste(httr::content(resp), collapse = "\n"), - if (!must_work) " Staged dependencies will continue, ignoring this repository. Some packages may ", - "not be able to be installed and its package name is assumed to match repository name." - ) + cloned_repo <- tryCatch( + { + git_repo <- git2r::clone( + url = repo_url, local_path = repo_dir, + credentials = creds, progress = verbose >= 2 ) - } else{ - notification_function( - paste0( - "Repo ", repo, " could ", - "not be cloned. The git2r::clone error is: ", e$message, - if (!must_work) "\nStaged dependencies will continue, ignoring this repository. Some packages may ", - "not be able to be installed and its package name is assumed to match repository name." + }, + error = function(e) { + # catch some common errors + # only do this when cloning because the API calls introduce quite some time overhead + host <- paste(utils::head(strsplit(repo_url, "/", fixed = TRUE)[[1]], -2), collapse = "/") + repo <- paste(utils::tail(strsplit(repo_url, "/", fixed = TRUE)[[1]], 2), collapse = "/") + repo <- substr(repo, start = 0, stop = nchar(repo) - nchar(".git")) + + if (!identical(httr::status_code(httr::HEAD(host)), 200L)) { + stop("Host ", host, " not reachable") + } + + notification_function <- if (must_work) stop else warning + + resp <- get_repo_access(repo, host, token_envvar) + if (!is.null(resp) && httr::status_code(resp) > 200) { + notification_function( + paste0( + "You cannot access ", repo, " at host ", host, + ". If you expect to be able to access this repo then ", + "check that repo and token in envvar '", token_envvar, + "' are correct.\n", + "The response's content was:\n", paste(httr::content(resp), collapse = "\n"), + if (!must_work) " Staged dependencies will continue, ignoring this repository. Some packages may ", + "not be able to be installed and its package name is assumed to match repository name." + ) ) - ) - } + } else { + notification_function( + paste0( + "Repo ", repo, " could ", + "not be cloned. The git2r::clone error is: ", e$message, + if (!must_work) "\nStaged dependencies will continue, ignoring this repository. Some packages may ", + "not be able to be installed and its package name is assumed to match repository name." + ) + ) + } - return(NULL) - }) + return(NULL) + } + ) if (is.null(cloned_repo)) { return(list(dir = as.character(NA), ref = as.character(NA), sha = as.character(NA), accessible = FALSE)) @@ -123,12 +127,17 @@ checkout_repo <- function(repo_dir, repo_url, select_ref_rule, token_envvar = NU git_repo <- git2r::repository(repo_dir) # prune (remove) remote branches that were deleted from remote git2r::config(git_repo, remote.origin.prune = "true") - tryCatch({ - git2r::fetch(git_repo, name = get_remote_name(git_repo, repo_url), credentials = creds, verbose = verbose >= 2) - }, error = function(cond) { - warning("Unable to fetch from remote for ", repo_dir, " using state of repo found in cache.\n", - "Error message when trying to fetch: ", cond$message) - }) + tryCatch( + { + git2r::fetch(git_repo, name = get_remote_name(git_repo, repo_url), credentials = creds, verbose = verbose >= 2) + }, + error = function(cond) { + warning( + "Unable to fetch from remote for ", repo_dir, " using state of repo found in cache.\n", + "Error message when trying to fetch: ", cond$message + ) + } + ) } check_only_remote_branches(git_repo, remote_name = get_remote_name(git_repo, repo_url)) @@ -150,14 +159,16 @@ checkout_repo <- function(repo_dir, repo_url, select_ref_rule, token_envvar = NU if (verbose >= 1) { message(paste(" - checkout tag", selected_ref, "in directory", repo_dir)) git2r::branch_create(commit = git2r::commits(repo = repo_dir, ref = selected_ref, n = 1)[[1]], force = TRUE, name = paste0("staged_dep_tag_", selected_ref)) - git2r::checkout(git_repo, branch = paste0("staged_dep_tag_", selected_ref), force = TRUE) + git2r::checkout(git_repo, branch = paste0("staged_dep_tag_", selected_ref), force = TRUE) } - } else{ + } else { stop("The selected reference should have a type attribute as 'branch' or 'tag'") } - return(list(dir = repo_dir, ref = selected_ref, - sha = get_short_sha(repo_dir), accessible = TRUE)) + return(list( + dir = repo_dir, ref = selected_ref, + sha = get_short_sha(repo_dir), accessible = TRUE + )) } # Install the external deps required for a package @@ -169,12 +180,14 @@ install_external_deps <- function(repo_dir, internal_pkg_deps, ...) { # So we create a temp directory containing this file and then call this function repo_dir_external <- tempfile(paste0(basename(repo_dir), "_externalDeps")) fs::dir_create(repo_dir_external) - fs::file_copy(file.path(repo_dir, "DESCRIPTION"), - file.path(repo_dir_external, "DESCRIPTION")) + fs::file_copy( + file.path(repo_dir, "DESCRIPTION"), + file.path(repo_dir_external, "DESCRIPTION") + ) # remove internal_pkg_deps from DESCRIPTION file desc_obj <- desc::desc(file.path(repo_dir_external, "DESCRIPTION")) - new_deps <- desc_obj$get_deps()[!desc_obj$get_deps()$package %in% internal_pkg_deps,] + new_deps <- desc_obj$get_deps()[!desc_obj$get_deps()$package %in% internal_pkg_deps, ] desc_obj$set_deps(new_deps) @@ -205,7 +218,6 @@ get_remote_name <- function(git_repo, repo_url) { remotes <- git2r::remotes(git_repo) for (remote in remotes) { - target_url <- git2r::remote_url(git_repo, remote = remote) target_url <- gsub("^(https://|git@ssh.|git@)|\\.git$", "", target_url) target_url <- gsub(":", "/", target_url, fixed = TRUE) @@ -251,7 +263,8 @@ install_repo_add_sha <- function(repo_dir, get_local_sha <- function(pkg_name) { # see remotes:::package2remote pkg_desc <- tryCatch(utils::packageDescription(pkg_name), - error = function(e) NA, warning = function(e) NA) + error = function(e) NA, warning = function(e) NA + ) if (identical(pkg_desc, NA)) { return(NULL) } @@ -262,7 +275,7 @@ install_repo_add_sha <- function(repo_dir, commit_sha <- git2r::sha(git2r::repository_head(repo_dir)) git_status <- git2r::status(repo_dir) if ((length(git_status$staged) > 0) || (length(git_status$unstaged) > 0) || - (length(git_status$untracked) > 0)) { + (length(git_status$untracked) > 0)) { # check that there are no changes (so that sha is correct), there should be no # untracked files (because the user might work on a local repo on a new file that is # still untracked) @@ -281,8 +294,8 @@ install_repo_add_sha <- function(repo_dir, metadata <- list( RemoteType = "git2r", RemoteUrl = git2r::remote_url(repo_dir), - #RemoteSubdir = NULL, - #RemoteRef = x$ref, + # RemoteSubdir = NULL, + # RemoteRef = x$ref, RemoteSha = commit_sha ) diff --git a/R/graph_methods.R b/R/graph_methods.R index df7e6a9..4f91d35 100644 --- a/R/graph_methods.R +++ b/R/graph_methods.R @@ -10,12 +10,12 @@ #' child to its parents (upstream dependencies) #' @return vector listing parents before children #' @examples -#' staged.dependencies:::topological_sort(list(A = c(), B = c("A"), C = c("B"), D = c("A"))) -#' staged.dependencies:::topological_sort(list(D = c("A"), A = c(), B = c("A"), C = c("B"))) -#' staged.dependencies:::topological_sort(list(D = c("A"), B = c("A"), C = c("B"), A = c())) +#' staged.dependencies:::topological_sort(list(A = c(), B = c("A"), C = c("B"), D = c("A"))) +#' staged.dependencies:::topological_sort(list(D = c("A"), A = c(), B = c("A"), C = c("B"))) +#' staged.dependencies:::topological_sort(list(D = c("A"), B = c("A"), C = c("B"), A = c())) #' \dontrun{ -#' # cycle -#' topological_sort(list(A = c("B"), B = c("C", "A"), C = c())) +#' # cycle +#' topological_sort(list(A = c("B"), B = c("C", "A"), C = c())) #' } topological_sort <- function(graph) { # compute in-degrees @@ -55,8 +55,10 @@ topological_sort <- function(graph) { } if (visited != length(in_degrees)) { - stop("Dependency graph is not a directed acyclic graph. Cycles involving: ", - paste0(setdiff(names(in_degrees), sorted), collapse = " ")) + stop( + "Dependency graph is not a directed acyclic graph. Cycles involving: ", + paste0(setdiff(names(in_degrees), sorted), collapse = " ") + ) } else { return(unlist(sorted)) } diff --git a/R/host.R b/R/host.R index da89749..9dba181 100644 --- a/R/host.R +++ b/R/host.R @@ -1,17 +1,16 @@ -get_repo_access <- function(repo, host, token_envvar){ - +get_repo_access <- function(repo, host, token_envvar) { host_type <- NULL if (host == "https://github.com" || token_envvar == "GITHUB_PAT") { host_type <- "github" } else if (host == "https://gitlab.com" || token_envvar == "GITLAB_PAT") { - host_type = "gitlab" + host_type <- "gitlab" } else { return(NULL) } if (host_type == "github") { resp <- httr::GET( - paste0(gsub(":\\/\\/", ":\\/\\/api.",host), "/repos/", repo), + paste0(gsub(":\\/\\/", ":\\/\\/api.", host), "/repos/", repo), # `token` argument not working httr::add_headers(c(Authorization = paste("token", Sys.getenv(token_envvar)))) ) diff --git a/R/ref_strategy.R b/R/ref_strategy.R index 6ee872e..36e33c6 100644 --- a/R/ref_strategy.R +++ b/R/ref_strategy.R @@ -24,26 +24,33 @@ #' @export #' #' @examples -#' determine_ref("feature1", +#' determine_ref( +#' "feature1", #' data.frame(ref = c("main", "feature1"), type = "branch") #' ) == structure("feature1", type = "branch") #' -#' determine_ref("feature1@devel", +#' determine_ref( +#' "feature1@devel", #' data.frame(ref = c("main", "devel", "feature1"), type = "branch") #' ) == structure("devel", type = "branch") #' #' determine_ref( #' ref = "fix1@feature1@devel", #' available_refs = data.frame( -#' ref = c("main", "devel", "feature1", "feature1@devel", -#' "fix1@feature1@devel", "fix1"), -#' type = "branch") +#' ref = c( +#' "main", "devel", "feature1", "feature1@devel", +#' "fix1@feature1@devel", "fix1" +#' ), +#' type = "branch" +#' ) #' ) == structure("fix1@feature1@devel", type = "branch") #' #' determine_ref( #' "fix1@feature1@devel", -#' data.frame(ref = c("main", "devel", "feature1", "feature1@devel", "fix1"), -#' type = "branch") +#' data.frame( +#' ref = c("main", "devel", "feature1", "feature1@devel", "fix1"), +#' type = "branch" +#' ) #' ) == structure("feature1@devel", type = "branch") #' #' determine_ref( @@ -57,15 +64,16 @@ #' # determine_ref("feature1@release", data.frame(ref = c("master", "devel"), type = "branch")) #' #' # tag examples -#' determine_ref("v0.1", +#' determine_ref( +#' "v0.1", #' data.frame(ref = c("main", "devel", "feature1", "v0.1"), type = c(rep("branch", 3), "tag")) #' ) == structure("v0.1", type = "tag") #' -#' determine_ref("v0.2", +#' determine_ref( +#' "v0.2", #' data.frame(ref = c("main", "devel", "feature1", "v0.1"), type = c(rep("branch", 3), "tag")) #' ) == structure("main", type = "branch") #' -#' determine_ref <- function(ref, available_refs, fallback_branch = "main", branch_sep = "@") { stopifnot( is_non_empty_char(ref), @@ -75,7 +83,7 @@ determine_ref <- function(ref, available_refs, fallback_branch = "main", branch_ ) # check for tag - if (ref %in% available_refs$ref[available_refs$type == "tag"]){ + if (ref %in% available_refs$ref[available_refs$type == "tag"]) { attr(ref, "type") <- "tag" return(ref) } @@ -96,8 +104,10 @@ determine_ref <- function(ref, available_refs, fallback_branch = "main", branch_ } } - stop("Available refs '", toString(available_refs$ref), "' must include at least one of '", - toString(branches_to_check), "'") + stop( + "Available refs '", toString(available_refs$ref), "' must include at least one of '", + toString(branches_to_check), "'" + ) } # infer the ref if it is null @@ -118,8 +128,10 @@ check_ref_consistency <- function(ref, project = ".", remote_name = "origin", fa fallback_branch = fallback_branch ) if (current_branch != expected_current_branch) { - warning("Branch ", ref, " would match ", expected_current_branch, " in project ", project, - ", but currently checked out branch is ", current_branch) + warning( + "Branch ", ref, " would match ", expected_current_branch, " in project ", project, + ", but currently checked out branch is ", current_branch + ) } } } diff --git a/R/renv.R b/R/renv.R index eb3f746..7e5aec2 100644 --- a/R/renv.R +++ b/R/renv.R @@ -15,6 +15,7 @@ get_renv_lock_from_repo_dir <- function(repo_dir, renv_profile = NULL) { error = function(cond) { warning(paste("Unable to open renv.lock file", renv_file, "so it will be ignored")) NULL - }) + } + ) return(renv_lock) } diff --git a/R/rstudio_jobs.R b/R/rstudio_jobs.R index 89e4247..97c8787 100644 --- a/R/rstudio_jobs.R +++ b/R/rstudio_jobs.R @@ -33,9 +33,9 @@ install_deps_job <- function(project = ".", project_type = "local", verbose = 1, create_args_str <- paste(deparse(create_args), collapse = "\n") install_args <- c(list(dep_structure = substitute(x), verbose = verbose), list(...)) install_args_str <- paste(deparse(install_args), collapse = "\n") - script <- glue::glue('x <- do.call(staged.dependencies::dependency_table, {create_args_str}) + script <- glue::glue("x <- do.call(staged.dependencies::dependency_table, {create_args_str}) print(x) - do.call(staged.dependencies::install_deps, {install_args_str})') + do.call(staged.dependencies::install_deps, {install_args_str})") dot_args <- list(...) if (!is.null(dot_args[["install_project"]]) && !dot_args[["install_project"]]) { @@ -55,8 +55,10 @@ install_deps_job <- function(project = ".", project_type = "local", verbose = 1, #' @examples #' \dontrun{ #' check_downstream_job(check_args = Sys.getenv("RCMDCHECK_ARGS")) -#' check_downstream_job(check_args = Sys.getenv("RCMDCHECK_ARGS"), -#' list(create_arg = list(ref = "6_makegraph@main"))) +#' check_downstream_job( +#' check_args = Sys.getenv("RCMDCHECK_ARGS"), +#' list(create_arg = list(ref = "6_makegraph@main")) +#' ) #' check_downstream_job(only_tests = TRUE) #' } check_downstream_job <- function(project = ".", verbose = 1, @@ -66,8 +68,8 @@ check_downstream_job <- function(project = ".", verbose = 1, create_args_str <- paste(deparse(create_args), collapse = "\n") check_downstream_args <- c(list(dep_structure = substitute(x), verbose = verbose), list(...)) check_downstream_args_str <- paste(deparse(check_downstream_args), collapse = "\n") - script <- glue::glue('x <- do.call(staged.dependencies::dependency_table, {create_args_str}) + script <- glue::glue("x <- do.call(staged.dependencies::dependency_table, {create_args_str}) print(x) - do.call(staged.dependencies::check_downstream, {check_downstream_args_str})') + do.call(staged.dependencies::check_downstream, {check_downstream_args_str})") run_job(script, "check_downstream", paste0("Check downstream of ", basename(project))) } diff --git a/R/utils.R b/R/utils.R index bbe0e38..66410dc 100644 --- a/R/utils.R +++ b/R/utils.R @@ -3,7 +3,7 @@ cat_nl <- function(...) cat(paste0(paste(...), "\n")) # cat_nl("fff", "gg") # output message if verbose argument is at least required_verbose -message_if_verbose <- function(..., verbose, required_verbose = 1){ +message_if_verbose <- function(..., verbose, required_verbose = 1) { if (verbose >= required_verbose) { message(...) } @@ -114,14 +114,16 @@ validate_staged_deps_yaml <- function(content, file_name = "") { check_single_entry <- function(content, expected_fields, field_name) { # check the required contents exist if (!(all(expected_fields %in% names(content)))) { - stop("File ", file_name , " invalid, field ", field_name, + stop( + "File ", file_name, " invalid, field ", field_name, " cannot be an array and must have entries ", toString(expected_fields) ) } # and are unnamed and character scalars - lapply(expected_fields, function(x){ + lapply(expected_fields, function(x) { if (!rlang::is_scalar_character(content[[x]]) || rlang::is_named(content[[x]])) { - stop("File ", file_name , " invalid, field ", field_name, + stop( + "File ", file_name, " invalid, field ", field_name, " must have non-array character values ", toString(expected_fields) ) } @@ -132,28 +134,27 @@ validate_staged_deps_yaml <- function(content, file_name = "") { # first check the required fields exist required_fields <- lapply(required_schema, "[[", "name") if (!all(required_fields %in% names(content))) { - stop("File ", file_name , " invalid, it must contain fields ", toString(required_fields)) + stop("File ", file_name, " invalid, it must contain fields ", toString(required_fields)) } # next check the contents of the fields is as expected - lapply(required_schema, function(field){ + lapply(required_schema, function(field) { # extract the contents for this field sub_content <- content[[field$name]] # check not NULL if required and exit if NULL and that's OK if (!field$nullable && is.null(sub_content)) { - stop("File ", file_name , " invalid, field ", field$name, " cannot be empty") + stop("File ", file_name, " invalid, field ", field$name, " cannot be empty") } - if (is.null(sub_content)){ + if (is.null(sub_content)) { return(invisible(NULL)) } # if field is not array type check content is expected if (!field$array) { check_single_entry(sub_content, field$subfields, field$name) - } - else { # if field is array type - for each element of array check content is expected + } else { # if field is array type - for each element of array check content is expected lapply(sub_content, check_single_entry, field$subfields, field$name) } }) @@ -163,9 +164,10 @@ validate_staged_deps_yaml <- function(content, file_name = "") { # check that two sets agree and throw an error message detailing difference otherwise check_set_equal <- function(x, y, pre_msg = "", return_error = FALSE) { if (!setequal(x, y)) { - err_msg <- paste0(pre_msg, "Sets do not agree, ", - "setdiff x \\ y is '", toString(setdiff(x, y)), "'", - ", setdiff y \\ x is '", toString(setdiff(y, x)), "'" + err_msg <- paste0( + pre_msg, "Sets do not agree, ", + "setdiff x \\ y is '", toString(setdiff(x, y)), "'", + ", setdiff y \\ x is '", toString(setdiff(y, x)), "'" ) if (return_error) { return(err_msg) @@ -196,9 +198,11 @@ get_yaml_deps_info <- function(repo_dir) { validate_staged_deps_yaml(content, file_name = yaml_file) content } else { - list(upstream_repos = list(), downstream_repos = list(), - # function() so it does not error immediately - current_repo = function() stop("Directory ", repo_dir, " has no ", STAGEDDEPS_FILENAME)) + list( + upstream_repos = list(), downstream_repos = list(), + # function() so it does not error immediately + current_repo = function() stop("Directory ", repo_dir, " has no ", STAGEDDEPS_FILENAME) + ) } } diff --git a/R/zzz.R b/R/zzz.R index 5ccf876..386a726 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -36,5 +36,3 @@ get_storage_dir <- function() { if (any(toset)) options(op.package[toset]) setup_storage_dir(path.expand("~/.staged.dependencies")) } - - diff --git a/man/build_check_install.Rd b/man/build_check_install.Rd index fe11ef6..088e7dd 100644 --- a/man/build_check_install.Rd +++ b/man/build_check_install.Rd @@ -8,8 +8,7 @@ build_check_install( dep_structure, install_direction = "all", steps = c("build", "check", "install"), - rcmd_args = list(check = c("--no-multiarch", "--with-keep.source", - "--install-tests")), + rcmd_args = list(check = c("--no-multiarch", "--with-keep.source", "--install-tests")), artifact_dir = tempfile(), install_external_deps = TRUE, upgrade = "never", @@ -74,9 +73,8 @@ Build, check and install internal dependencies } \examples{ \dontrun{ - x <- dependency_table(project = ".", verbose = 1) - build_check_install(x, steps = c("build", "check"), verbose = 1) - build_check_install(x, artifact_dir = "../output") - +x <- dependency_table(project = ".", verbose = 1) +build_check_install(x, steps = c("build", "check"), verbose = 1) +build_check_install(x, artifact_dir = "../output") } } diff --git a/man/check_downstream_job.Rd b/man/check_downstream_job.Rd index c826f6d..158a531 100644 --- a/man/check_downstream_job.Rd +++ b/man/check_downstream_job.Rd @@ -54,8 +54,10 @@ Check & install downstream job \examples{ \dontrun{ check_downstream_job(check_args = Sys.getenv("RCMDCHECK_ARGS")) -check_downstream_job(check_args = Sys.getenv("RCMDCHECK_ARGS"), - list(create_arg = list(ref = "6_makegraph@main"))) +check_downstream_job( + check_args = Sys.getenv("RCMDCHECK_ARGS"), + list(create_arg = list(ref = "6_makegraph@main")) +) check_downstream_job(only_tests = TRUE) } } diff --git a/man/dependency_table.Rd b/man/dependency_table.Rd index 64eba79..f1dad36 100644 --- a/man/dependency_table.Rd +++ b/man/dependency_table.Rd @@ -74,13 +74,17 @@ Create dependency structure of your package collection } \examples{ \dontrun{ - dependency_table(verbose = 1) - dependency_table(project = "openpharma/stageddeps.food@https://github.com", - project_type = "repo@host", - ref = "main") - x <- dependency_table(project = "path/to/project", - direction = c("upstream")) - print(x) - plot(x) +dependency_table(verbose = 1) +dependency_table( + project = "openpharma/stageddeps.food@https://github.com", + project_type = "repo@host", + ref = "main" +) +x <- dependency_table( + project = "path/to/project", + direction = c("upstream") +) +print(x) +plot(x) } } diff --git a/man/determine_ref.Rd b/man/determine_ref.Rd index 50af9d9..9edddf8 100644 --- a/man/determine_ref.Rd +++ b/man/determine_ref.Rd @@ -33,26 +33,33 @@ among the available branches, it searches in the order \code{name1@name2@...@nameN}, \code{name2@name3@...@nameN}, \code{name3@name4@...@nameN}, ..., \code{nameN} } \examples{ -determine_ref("feature1", +determine_ref( + "feature1", data.frame(ref = c("main", "feature1"), type = "branch") ) == structure("feature1", type = "branch") -determine_ref("feature1@devel", +determine_ref( + "feature1@devel", data.frame(ref = c("main", "devel", "feature1"), type = "branch") ) == structure("devel", type = "branch") determine_ref( ref = "fix1@feature1@devel", available_refs = data.frame( - ref = c("main", "devel", "feature1", "feature1@devel", - "fix1@feature1@devel", "fix1"), - type = "branch") + ref = c( + "main", "devel", "feature1", "feature1@devel", + "fix1@feature1@devel", "fix1" + ), + type = "branch" + ) ) == structure("fix1@feature1@devel", type = "branch") determine_ref( "fix1@feature1@devel", - data.frame(ref = c("main", "devel", "feature1", "feature1@devel", "fix1"), - type = "branch") + data.frame( + ref = c("main", "devel", "feature1", "feature1@devel", "fix1"), + type = "branch" + ) ) == structure("feature1@devel", type = "branch") determine_ref( @@ -66,13 +73,14 @@ determine_ref("feature1@release", data.frame(ref = c("main", "devel"), type = "b # determine_ref("feature1@release", data.frame(ref = c("master", "devel"), type = "branch")) # tag examples -determine_ref("v0.1", +determine_ref( + "v0.1", data.frame(ref = c("main", "devel", "feature1", "v0.1"), type = c(rep("branch", 3), "tag")) ) == structure("v0.1", type = "tag") -determine_ref("v0.2", +determine_ref( + "v0.2", data.frame(ref = c("main", "devel", "feature1", "v0.1"), type = c(rep("branch", 3), "tag")) ) == structure("main", type = "branch") - } diff --git a/man/get_all_external_dependencies.Rd b/man/get_all_external_dependencies.Rd index 18debdc..90976b6 100644 --- a/man/get_all_external_dependencies.Rd +++ b/man/get_all_external_dependencies.Rd @@ -50,19 +50,21 @@ List the external R packages required to be installed } \examples{ \dontrun{ - x <- dependency_table("openpharma/stageddeps.electricity", - project_type = "repo@host", feature = "main") +x <- dependency_table("openpharma/stageddeps.electricity", + project_type = "repo@host", feature = "main" +) - # get external package dependencies - ex_deps <- get_all_external_dependencies(x) - print(ex_deps) +# get external package dependencies +ex_deps <- get_all_external_dependencies(x) +print(ex_deps) - # get system dependencies (in this case there are none) - unique(unlist(lapply(ex_deps, - function(pkg, ...) - remotes::system_requirements(package = pkg, ...), - os = "ubuntu", - os_release = "20.04") - )) +# get system dependencies (in this case there are none) +unique(unlist(lapply(ex_deps, + function(pkg, ...) { + remotes::system_requirements(package = pkg, ...) + }, + os = "ubuntu", + os_release = "20.04" +))) } } diff --git a/man/install_deps.Rd b/man/install_deps.Rd index b24de11..118d796 100644 --- a/man/install_deps.Rd +++ b/man/install_deps.Rd @@ -62,7 +62,6 @@ install_deps(x) # install all dependencies install_deps(x, install_direction = "all") - } } \seealso{ diff --git a/man/install_deps_app.Rd b/man/install_deps_app.Rd index f714a79..6f9ea04 100644 --- a/man/install_deps_app.Rd +++ b/man/install_deps_app.Rd @@ -62,6 +62,6 @@ in the package's staged dependencies yaml files starting from \code{project}. } \examples{ \dontrun{ - install_deps_app("openpharma/stageddeps.food") +install_deps_app("openpharma/stageddeps.food") } } diff --git a/man/topological_sort.Rd b/man/topological_sort.Rd index 8de6437..483e34a 100644 --- a/man/topological_sort.Rd +++ b/man/topological_sort.Rd @@ -21,11 +21,11 @@ in the returned list, parents appear before their children. Implementation of Kahn algorithm with a modification to maintain the order of input elements. } \examples{ - staged.dependencies:::topological_sort(list(A = c(), B = c("A"), C = c("B"), D = c("A"))) - staged.dependencies:::topological_sort(list(D = c("A"), A = c(), B = c("A"), C = c("B"))) - staged.dependencies:::topological_sort(list(D = c("A"), B = c("A"), C = c("B"), A = c())) +staged.dependencies:::topological_sort(list(A = c(), B = c("A"), C = c("B"), D = c("A"))) +staged.dependencies:::topological_sort(list(D = c("A"), A = c(), B = c("A"), C = c("B"))) +staged.dependencies:::topological_sort(list(D = c("A"), B = c("A"), C = c("B"), A = c())) \dontrun{ - # cycle - topological_sort(list(A = c("B"), B = c("C", "A"), C = c())) +# cycle +topological_sort(list(A = c("B"), B = c("C", "A"), C = c())) } } diff --git a/renv.lock b/renv.lock index 57eae72..ece62e4 100644 --- a/renv.lock +++ b/renv.lock @@ -1,6 +1,6 @@ { "R": { - "Version": "4.1.0", + "Version": "4.2.0", "Repositories": [ { "Name": "CRAN", @@ -19,10 +19,10 @@ }, "Rcpp": { "Package": "Rcpp", - "Version": "1.0.8.3", + "Version": "1.0.9", "Source": "Repository", "Repository": "CRAN", - "Hash": "32e79b908fda56ee57fe518a8d37b864", + "Hash": "e9c08b94391e9f3f97355841229124f2", "Requirements": [] }, "askpass": { @@ -45,10 +45,10 @@ }, "brew": { "Package": "brew", - "Version": "1.0-7", + "Version": "1.0-8", "Source": "Repository", "Repository": "CRAN", - "Hash": "38875ea52350ff4b4c03849fc69736c8", + "Hash": "d69a786e85775b126bddbee185ae6084", "Requirements": [] }, "brio": { @@ -61,14 +61,16 @@ }, "bslib": { "Package": "bslib", - "Version": "0.3.1", + "Version": "0.4.0", "Source": "Repository", "Repository": "CRAN", - "Hash": "56ae7e1987b340186a8a5a157c2ec358", + "Hash": "be5ee090716ce1671be6cd5d7c34d091", "Requirements": [ + "cachem", "htmltools", "jquerylib", "jsonlite", + "memoise", "rlang", "sass" ] @@ -86,10 +88,10 @@ }, "callr": { "Package": "callr", - "Version": "3.7.0", + "Version": "3.7.2", "Source": "Repository", "Repository": "CRAN", - "Hash": "461aa75a11ce2400245190ef5d3995df", + "Hash": "358689cac9fe93b1bb3a19088d2dbed8", "Requirements": [ "R6", "processx" @@ -97,13 +99,11 @@ }, "cli": { "Package": "cli", - "Version": "3.3.0", + "Version": "3.4.1", "Source": "Repository", "Repository": "CRAN", - "Hash": "23abf173c2b783dcc43379ab9bba00ee", - "Requirements": [ - "glue" - ] + "Hash": "0d297d01734d2bcea40197bd4971a764", + "Requirements": [] }, "clipr": { "Package": "clipr", @@ -121,22 +121,6 @@ "Hash": "2ba81b120c1655ab696c935ef33ea716", "Requirements": [] }, - "covr": { - "Package": "covr", - "Version": "3.5.1", - "Source": "Repository", - "Repository": "CRAN", - "Hash": "6d80a9fc3c0c8473153b54fa54719dfd", - "Requirements": [ - "crayon", - "digest", - "httr", - "jsonlite", - "rex", - "withr", - "yaml" - ] - }, "cpp11": { "Package": "cpp11", "Version": "0.4.2", @@ -147,10 +131,10 @@ }, "crayon": { "Package": "crayon", - "Version": "1.5.1", + "Version": "1.5.2", "Source": "Repository", "Repository": "CRAN", - "Hash": "8dc45fd8a1ee067a92b85ef274e66d6a", + "Hash": "e8a1e41acf02548751f45c718d55aa6a", "Requirements": [] }, "credentials": { @@ -169,18 +153,18 @@ }, "curl": { "Package": "curl", - "Version": "4.3.2", + "Version": "4.3.3", "Source": "Repository", "Repository": "CRAN", - "Hash": "022c42d49c28e95d69ca60446dbabf88", + "Hash": "0eb86baa62f06e8855258fa5a8048667", "Requirements": [] }, "desc": { "Package": "desc", - "Version": "1.4.1", + "Version": "1.4.2", "Source": "Repository", "Repository": "CRAN", - "Hash": "eebd27ee58fcc58714eedb7aa07d8ad1", + "Hash": "6b9602c7ebbe87101a9c8edb6e8b6d21", "Requirements": [ "R6", "cli", @@ -189,29 +173,30 @@ }, "devtools": { "Package": "devtools", - "Version": "2.4.3", + "Version": "2.4.5", "Source": "Repository", "Repository": "CRAN", - "Hash": "fc35e13bb582e5fe6f63f3d647a4cbe5", + "Hash": "ea5bc8b4a6a01e4f12d98b58329930bb", "Requirements": [ - "callr", "cli", "desc", "ellipsis", "fs", - "httr", "lifecycle", "memoise", + "miniUI", "pkgbuild", + "pkgdown", "pkgload", + "profvis", "rcmdcheck", "remotes", "rlang", "roxygen2", - "rstudioapi", "rversions", "sessioninfo", "testthat", + "urlchecker", "usethis", "withr" ] @@ -236,10 +221,10 @@ }, "downlit": { "Package": "downlit", - "Version": "0.4.0", + "Version": "0.4.2", "Source": "Repository", "Repository": "CRAN", - "Hash": "ba63dc9ab5a31f3209892437e40c5f60", + "Hash": "79bf3f66590752ffbba20f8d2da94c7c", "Requirements": [ "brio", "desc", @@ -249,15 +234,16 @@ "memoise", "rlang", "vctrs", + "withr", "yaml" ] }, "dplyr": { "Package": "dplyr", - "Version": "1.0.9", + "Version": "1.0.10", "Source": "Repository", "Repository": "CRAN", - "Hash": "f0bda1627a7f5d3f9a0b5add931596ac", + "Hash": "539412282059f7f0c07295723d23f987", "Requirements": [ "R6", "generics", @@ -283,10 +269,10 @@ }, "evaluate": { "Package": "evaluate", - "Version": "0.15", + "Version": "0.17", "Source": "Repository", "Repository": "CRAN", - "Hash": "699a7a93d08c962d9f8950b2d7a227f1", + "Hash": "9171b012a55a1ef53f1442b1d798a3b4", "Requirements": [] }, "fansi": { @@ -307,10 +293,10 @@ }, "fontawesome": { "Package": "fontawesome", - "Version": "0.2.2", + "Version": "0.3.0", "Source": "Repository", "Repository": "CRAN", - "Hash": "55624ed409e46c5f358b2c060be87f67", + "Hash": "a36c4a3eade472039a3ec8cb824e6dc4", "Requirements": [ "htmltools", "rlang" @@ -326,18 +312,18 @@ }, "generics": { "Package": "generics", - "Version": "0.1.2", + "Version": "0.1.3", "Source": "Repository", "Repository": "CRAN", - "Hash": "177475892cf4a55865868527654a7741", + "Hash": "15e9634c0fcd294799e9b2e929ed1b86", "Requirements": [] }, "gert": { "Package": "gert", - "Version": "1.6.0", + "Version": "1.9.1", "Source": "Repository", "Repository": "CRAN", - "Hash": "98c014c4c933f23ea5a0321a4d0b588b", + "Hash": "9a091a6d2fb91e43afd4337e2dcef2e7", "Requirements": [ "askpass", "credentials", @@ -349,10 +335,10 @@ }, "gh": { "Package": "gh", - "Version": "1.3.0", + "Version": "1.3.1", "Source": "Repository", "Repository": "CRAN", - "Hash": "38c2580abbda249bd6afeec00d14f531", + "Hash": "b6a12054ee13dce0f6696c019c10e539", "Requirements": [ "cli", "gitcreds", @@ -371,10 +357,10 @@ }, "gitcreds": { "Package": "gitcreds", - "Version": "0.1.1", + "Version": "0.1.2", "Source": "Repository", "Repository": "CRAN", - "Hash": "f3aefccc1cc50de6338146b62f115de8", + "Hash": "ab08ac61f3e1be454ae21911eb8bc2fe", "Requirements": [] }, "glue": { @@ -397,10 +383,10 @@ }, "htmltools": { "Package": "htmltools", - "Version": "0.5.2", + "Version": "0.5.3", "Source": "Repository", "Repository": "CRAN", - "Hash": "526c484233f42522278ab06fb185cb26", + "Hash": "6496090a9e00f8354b811d1a2d47b566", "Requirements": [ "base64enc", "digest", @@ -422,10 +408,10 @@ }, "httpuv": { "Package": "httpuv", - "Version": "1.6.5", + "Version": "1.6.6", "Source": "Repository", "Repository": "CRAN", - "Hash": "97fe71f0a4a1c9890e6c2128afa04bc0", + "Hash": "fd090e236ae2dc0f0cdf33a9ec83afb6", "Requirements": [ "R6", "Rcpp", @@ -435,10 +421,10 @@ }, "httr": { "Package": "httr", - "Version": "1.4.3", + "Version": "1.4.4", "Source": "Repository", "Repository": "CRAN", - "Hash": "88d1b310583777edf01ccd1216fb0b2b", + "Hash": "57557fac46471f0dbbf44705cc6a5c8c", "Requirements": [ "R6", "curl", @@ -467,18 +453,18 @@ }, "jsonlite": { "Package": "jsonlite", - "Version": "1.8.0", + "Version": "1.8.2", "Source": "Repository", "Repository": "CRAN", - "Hash": "d07e729b27b372429d42d24d503613a0", + "Hash": "2e7ed071fd6bd047fe2366d3adf4fe46", "Requirements": [] }, "knitr": { "Package": "knitr", - "Version": "1.39", + "Version": "1.40", "Source": "Repository", "Repository": "CRAN", - "Hash": "029ab7c4badd3cf8af69016b2ba27493", + "Hash": "caea8b0f899a0b1738444b9bc47067e7", "Requirements": [ "evaluate", "highr", @@ -498,21 +484,14 @@ "rlang" ] }, - "lazyeval": { - "Package": "lazyeval", - "Version": "0.2.2", - "Source": "Repository", - "Repository": "CRAN", - "Hash": "d908914ae53b04d4c0c0fd72ecc35370", - "Requirements": [] - }, "lifecycle": { "Package": "lifecycle", - "Version": "1.0.1", + "Version": "1.0.3", "Source": "Repository", "Repository": "CRAN", - "Hash": "a6b6d352e3ed897373ab19d8395c98d0", + "Hash": "001cecbeac1cff9301bdc3775ee46a86", "Requirements": [ + "cli", "glue", "rlang" ] @@ -567,24 +546,22 @@ }, "openssl": { "Package": "openssl", - "Version": "2.0.0", + "Version": "2.0.3", "Source": "Repository", "Repository": "CRAN", - "Hash": "cf4329aac12c2c44089974559c18e446", + "Hash": "b9621e75c0652041002a19609fb23c5a", "Requirements": [ "askpass" ] }, "pillar": { "Package": "pillar", - "Version": "1.7.0", + "Version": "1.8.1", "Source": "Repository", "Repository": "CRAN", - "Hash": "51dfc97e1b7069e9f7e6f83f3589c22e", + "Hash": "f2316df30902c81729ae9de95ad5a608", "Requirements": [ "cli", - "crayon", - "ellipsis", "fansi", "glue", "lifecycle", @@ -620,14 +597,14 @@ }, "pkgdown": { "Package": "pkgdown", - "Version": "2.0.3", + "Version": "2.0.6", "Source": "Repository", "Repository": "CRAN", - "Hash": "ec3139021900fa27faae7a821b732bf8", + "Hash": "f958d0b2a5dabc5ffd414f062b1ffbe7", "Requirements": [ "bslib", "callr", - "crayon", + "cli", "desc", "digest", "downlit", @@ -649,17 +626,18 @@ }, "pkgload": { "Package": "pkgload", - "Version": "1.2.4", + "Version": "1.3.0", "Source": "Repository", "Repository": "CRAN", - "Hash": "7533cd805940821bf23eaf3c8d4c1735", + "Hash": "4b20f937a363c78a5730265c1925f54a", "Requirements": [ "cli", "crayon", "desc", + "fs", + "glue", "rlang", "rprojroot", - "rstudioapi", "withr" ] }, @@ -681,15 +659,26 @@ }, "processx": { "Package": "processx", - "Version": "3.5.3", + "Version": "3.7.0", "Source": "Repository", "Repository": "CRAN", - "Hash": "8bbae1a548d0d3fdf6647bdd9d35bf6d", + "Hash": "f91df0f5f31ffdf88bc0b624f5ebab0f", "Requirements": [ "R6", "ps" ] }, + "profvis": { + "Package": "profvis", + "Version": "0.3.7", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "e9d21e79848e02e524bea6f5bd53e7e4", + "Requirements": [ + "htmlwidgets", + "stringr" + ] + }, "promises": { "Package": "promises", "Version": "1.2.0.1", @@ -706,18 +695,18 @@ }, "ps": { "Package": "ps", - "Version": "1.7.0", + "Version": "1.7.1", "Source": "Repository", "Repository": "CRAN", - "Hash": "eef74b13f32cae6bb0d495e53317c44c", + "Hash": "8b93531308c01ad0e56d9eadcc0c4fcd", "Requirements": [] }, "purrr": { "Package": "purrr", - "Version": "0.3.4", + "Version": "0.3.5", "Source": "Repository", "Repository": "CRAN", - "Hash": "97def703420c8ab10d8f0e6c72101e02", + "Hash": "54842a2443c76267152eface28d9e90a", "Requirements": [ "magrittr", "rlang" @@ -725,10 +714,10 @@ }, "ragg": { "Package": "ragg", - "Version": "1.2.2", + "Version": "1.2.3", "Source": "Repository", "Repository": "CRAN", - "Hash": "14932bb6f2739c771ca4ceaba6b4248e", + "Hash": "a7b1a8b453c5385786cdfa75aba57483", "Requirements": [ "systemfonts", "textshaping" @@ -783,36 +772,26 @@ }, "renv": { "Package": "renv", - "Version": "0.15.4", + "Version": "0.16.0", "Source": "Repository", "Repository": "CRAN", - "Hash": "c1078316e1d4f70275fc1ea60c0bc431", + "Hash": "c9e8442ab69bc21c9697ecf856c1e6c7", "Requirements": [] }, - "rex": { - "Package": "rex", - "Version": "1.2.1", - "Source": "Repository", - "Repository": "CRAN", - "Hash": "ae34cd56890607370665bee5bd17812f", - "Requirements": [ - "lazyeval" - ] - }, "rlang": { "Package": "rlang", - "Version": "1.0.2", + "Version": "1.0.6", "Source": "Repository", "Repository": "CRAN", - "Hash": "04884d9a75d778aca22c7154b8333ec9", + "Hash": "4ed1f8336c8d52c3e750adcdc57228a7", "Requirements": [] }, "rmarkdown": { "Package": "rmarkdown", - "Version": "2.14", + "Version": "2.17", "Source": "Repository", "Repository": "CRAN", - "Hash": "31b60a882fabfabf6785b8599ffeb8ba", + "Hash": "e97c8be593e010f93520e8215c0f9189", "Requirements": [ "bslib", "evaluate", @@ -828,10 +807,10 @@ }, "roxygen2": { "Package": "roxygen2", - "Version": "7.2.0", + "Version": "7.2.1", "Source": "Repository", "Repository": "CRAN", - "Hash": "b390c1d54fcd977cda48588e6172daba", + "Hash": "da1f278262e563c835345872f2fef537", "Requirements": [ "R6", "brew", @@ -860,18 +839,18 @@ }, "rstudioapi": { "Package": "rstudioapi", - "Version": "0.13", + "Version": "0.14", "Source": "Repository", "Repository": "CRAN", - "Hash": "06c85365a03fdaf699966cc1d3cf53ea", + "Hash": "690bd2acc42a9166ce34845884459320", "Requirements": [] }, "rversions": { "Package": "rversions", - "Version": "2.1.1", + "Version": "2.1.2", "Source": "Repository", "Repository": "CRAN", - "Hash": "f88fab00907b312f8b23ec13e2d437cb", + "Hash": "a9881dfed103e83f9de151dc17002cd1", "Requirements": [ "curl", "xml2" @@ -879,10 +858,10 @@ }, "sass": { "Package": "sass", - "Version": "0.4.1", + "Version": "0.4.2", "Source": "Repository", "Repository": "CRAN", - "Hash": "f37c0028d720bab3c513fd65d28c7234", + "Hash": "1b191143d7d3444d504277843f3a95fe", "Requirements": [ "R6", "fs", @@ -903,10 +882,10 @@ }, "shiny": { "Package": "shiny", - "Version": "1.7.1", + "Version": "1.7.2", "Source": "Repository", "Repository": "CRAN", - "Hash": "00344c227c7bd0ab5d78052c5d736c44", + "Hash": "4f7970a3edb0a153ac6b376785a1944a", "Requirements": [ "R6", "bslib", @@ -940,18 +919,18 @@ }, "stringi": { "Package": "stringi", - "Version": "1.7.6", + "Version": "1.7.8", "Source": "Repository", "Repository": "CRAN", - "Hash": "bba431031d30789535745a9627ac9271", + "Hash": "a68b980681bcbc84c7a67003fa796bfb", "Requirements": [] }, "stringr": { "Package": "stringr", - "Version": "1.4.0", + "Version": "1.4.1", "Source": "Repository", "Repository": "CRAN", - "Hash": "0759e6b6c0957edb1311028a49a35e76", + "Hash": "a66ad12140cd34d4f9dfcc19e84fc2a5", "Requirements": [ "glue", "magrittr", @@ -978,16 +957,15 @@ }, "testthat": { "Package": "testthat", - "Version": "3.1.4", + "Version": "3.1.5", "Source": "Repository", "Repository": "CRAN", - "Hash": "f76c2a02d0fdc24aa7a47ea34261a6e3", + "Hash": "6e3c4843f1ed0d3d90f35498671a001c", "Requirements": [ "R6", "brio", "callr", "cli", - "crayon", "desc", "digest", "ellipsis", @@ -1017,12 +995,11 @@ }, "tibble": { "Package": "tibble", - "Version": "3.1.7", + "Version": "3.1.8", "Source": "Repository", "Repository": "CRAN", - "Hash": "08415af406e3dd75049afef9552e7355", + "Hash": "56b6934ef0f8c68225949a8672fe1a8f", "Requirements": [ - "ellipsis", "fansi", "lifecycle", "magrittr", @@ -1034,10 +1011,10 @@ }, "tidyr": { "Package": "tidyr", - "Version": "1.2.0", + "Version": "1.2.1", "Source": "Repository", "Repository": "CRAN", - "Hash": "d8b95b7fee945d7da6888cf7eb71a49c", + "Hash": "cdb403db0de33ccd1b6f53b83736efa8", "Requirements": [ "cpp11", "dplyr", @@ -1054,34 +1031,47 @@ }, "tidyselect": { "Package": "tidyselect", - "Version": "1.1.2", + "Version": "1.2.0", "Source": "Repository", "Repository": "CRAN", - "Hash": "17f6da8cfd7002760a859915ce7eef8f", + "Hash": "79540e5fcd9e0435af547d885f184fd5", "Requirements": [ - "ellipsis", + "cli", "glue", - "purrr", + "lifecycle", "rlang", - "vctrs" + "vctrs", + "withr" ] }, "tinytex": { "Package": "tinytex", - "Version": "0.38", + "Version": "0.42", "Source": "Repository", "Repository": "CRAN", - "Hash": "759d047596ac173433985deddf313450", + "Hash": "7629c6c1540835d5248e6e7df265fa74", "Requirements": [ "xfun" ] }, + "urlchecker": { + "Package": "urlchecker", + "Version": "1.0.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "409328b8e1253c8d729a7836fe7f7a16", + "Requirements": [ + "cli", + "curl", + "xml2" + ] + }, "usethis": { "Package": "usethis", - "Version": "2.1.5", + "Version": "2.1.6", "Source": "Repository", "Repository": "CRAN", - "Hash": "c499f488e6dd7718accffaee5bc5a79b", + "Hash": "a67a22c201832b12c036cc059f1d137d", "Requirements": [ "cli", "clipr", @@ -1114,10 +1104,10 @@ }, "vctrs": { "Package": "vctrs", - "Version": "0.4.1", + "Version": "0.4.2", "Source": "Repository", "Repository": "CRAN", - "Hash": "8b54f22e2a58c4f275479c92ce041a57", + "Hash": "0e3dfc070b2a8f0478fcdf86fb33355d", "Requirements": [ "cli", "glue", @@ -1126,10 +1116,10 @@ }, "visNetwork": { "Package": "visNetwork", - "Version": "2.1.0", + "Version": "2.1.2", "Source": "Repository", "Repository": "CRAN", - "Hash": "99b515a03efb8dcc4e4be337f37bf087", + "Hash": "3e48b097e8d9a91ecced2ed4817a678d", "Requirements": [ "htmltools", "htmlwidgets", @@ -1171,10 +1161,10 @@ }, "xfun": { "Package": "xfun", - "Version": "0.31", + "Version": "0.33", "Source": "Repository", "Repository": "CRAN", - "Hash": "a318c6f752b8dcfe9fb74d897418ab2b", + "Hash": "1a666f915cd65072f4ccf5b2888d5d39", "Requirements": [] }, "xml2": { @@ -1213,10 +1203,10 @@ }, "zip": { "Package": "zip", - "Version": "2.2.0", + "Version": "2.2.1", "Source": "Repository", "Repository": "CRAN", - "Hash": "c7eef2996ac270a18c2715c997a727c5", + "Hash": "a7e91189fa51d9029a30eba3831ce53f", "Requirements": [] } } diff --git a/renv/.gitignore b/renv/.gitignore index cb06864..63b9ec4 100644 --- a/renv/.gitignore +++ b/renv/.gitignore @@ -1,3 +1,4 @@ +sandbox/ cellar/ library/ local/ diff --git a/renv/activate.R b/renv/activate.R index e961251..019b5a6 100644 --- a/renv/activate.R +++ b/renv/activate.R @@ -2,7 +2,7 @@ local({ # the requested version of renv - version <- "0.15.4" + version <- "0.16.0" # the project directory project <- getwd() @@ -54,7 +54,7 @@ local({ # mask 'utils' packages, will come first on the search path library(utils, lib.loc = .Library) - # unload renv if it's already been laoded + # unload renv if it's already been loaded if ("renv" %in% loadedNamespaces()) unloadNamespace("renv") @@ -185,43 +185,80 @@ local({ if (fixup) mode <- "w+b" - utils::download.file( + args <- list( url = url, destfile = destfile, mode = mode, quiet = TRUE ) + if ("headers" %in% names(formals(utils::download.file))) + args$headers <- renv_bootstrap_download_custom_headers(url) + + do.call(utils::download.file, args) + + } + + renv_bootstrap_download_custom_headers <- function(url) { + + headers <- getOption("renv.download.headers") + if (is.null(headers)) + return(character()) + + if (!is.function(headers)) + stopf("'renv.download.headers' is not a function") + + headers <- headers(url) + if (length(headers) == 0L) + return(character()) + + if (is.list(headers)) + headers <- unlist(headers, recursive = FALSE, use.names = TRUE) + + ok <- + is.character(headers) && + is.character(names(headers)) && + all(nzchar(names(headers))) + + if (!ok) + stop("invocation of 'renv.download.headers' did not return a named character vector") + + headers + } renv_bootstrap_download_cran_latest <- function(version) { spec <- renv_bootstrap_download_cran_latest_find(version) + type <- spec$type + repos <- spec$repos message("* Downloading renv ", version, " ... ", appendLF = FALSE) - type <- spec$type - repos <- spec$repos + baseurl <- utils::contrib.url(repos = repos, type = type) + ext <- if (identical(type, "source")) + ".tar.gz" + else if (Sys.info()[["sysname"]] == "Windows") + ".zip" + else + ".tgz" + name <- sprintf("renv_%s%s", version, ext) + url <- paste(baseurl, name, sep = "/") - info <- tryCatch( - utils::download.packages( - pkgs = "renv", - destdir = tempdir(), - repos = repos, - type = type, - quiet = TRUE - ), + destfile <- file.path(tempdir(), name) + status <- tryCatch( + renv_bootstrap_download_impl(url, destfile), condition = identity ) - if (inherits(info, "condition")) { + if (inherits(status, "condition")) { message("FAILED") return(FALSE) } # report success and return message("OK (downloaded ", type, ")") - info[1, 2] + destfile } @@ -314,9 +351,18 @@ local({ } # bail if it doesn't exist - if (!file.exists(tarball)) + if (!file.exists(tarball)) { + + # let the user know we weren't able to honour their request + fmt <- "* RENV_BOOTSTRAP_TARBALL is set (%s) but does not exist." + msg <- sprintf(fmt, tarball) + warning(msg) + + # bail return() + } + fmt <- "* Bootstrapping with tarball at path '%s'." msg <- sprintf(fmt, tarball) message(msg) @@ -669,7 +715,7 @@ local({ return(profile) # check for a profile file (nothing to do if it doesn't exist) - path <- renv_bootstrap_paths_renv("profile", profile = FALSE) + path <- renv_bootstrap_paths_renv("profile", profile = FALSE, project = project) if (!file.exists(path)) return(NULL) @@ -796,11 +842,25 @@ local({ renv_json_read <- function(file = NULL, text = NULL) { + # if jsonlite is loaded, use that instead + if ("jsonlite" %in% loadedNamespaces()) + renv_json_read_jsonlite(file, text) + else + renv_json_read_default(file, text) + + } + + renv_json_read_jsonlite <- function(file = NULL, text = NULL) { text <- paste(text %||% read(file), collapse = "\n") + jsonlite::fromJSON(txt = text, simplifyVector = FALSE) + } + + renv_json_read_default <- function(file = NULL, text = NULL) { # find strings in the JSON + text <- paste(text %||% read(file), collapse = "\n") pattern <- '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' - locs <- gregexpr(pattern, text)[[1]] + locs <- gregexpr(pattern, text, perl = TRUE)[[1]] # if any are found, replace them with placeholders replaced <- text @@ -829,8 +889,9 @@ local({ # transform the JSON into something the R parser understands transformed <- replaced - transformed <- gsub("[[{]", "list(", transformed) - transformed <- gsub("[]}]", ")", transformed) + transformed <- gsub("{}", "`names<-`(list(), character())", transformed, fixed = TRUE) + transformed <- gsub("[[{]", "list(", transformed, perl = TRUE) + transformed <- gsub("[]}]", ")", transformed, perl = TRUE) transformed <- gsub(":", "=", transformed, fixed = TRUE) text <- paste(transformed, collapse = "\n") diff --git a/tests/testthat/test-caching.R b/tests/testthat/test-caching.R index 8ba4250..a34d9a0 100644 --- a/tests/testthat/test-caching.R +++ b/tests/testthat/test-caching.R @@ -1,7 +1,6 @@ # does not require internet access, mocks git remote operations test_that("clear_cache", { - create_cache <- function(path) { fs::dir_create(file.path(path, "A")) fs::dir_create(file.path(path, "A", "AA")) @@ -30,14 +29,13 @@ test_that("clear_cache", { expect_message(clear_cache(pattern = "[Aa]"), "Directories remaining in cache:\nB\n") expect_length(fs::dir_ls(get_packages_cache_dir(), recurse = TRUE), 2) }) - }) test_that("rec_checkout_internal_deps works (with mocking checkout)", { # mock checkout_repo by copying the appropriate directory to the repo_dir directory - mockery::stub(rec_checkout_internal_deps, 'checkout_repo', function(repo_dir, repo_url, select_ref_rule, ...) { + mockery::stub(rec_checkout_internal_deps, "checkout_repo", function(repo_dir, repo_url, select_ref_rule, ...) { repo_name <- basename(repo_url) repo_name <- substr(repo_name, 0, nchar(repo_name) - nchar(".git")) cat(paste0("Mocking checkout_repo for ", repo_name, "\n")) @@ -56,8 +54,9 @@ test_that("rec_checkout_internal_deps works (with mocking checkout)", { capture.output(rec_checkout_internal_deps( list(list(repo = "openpharma/stageddeps.food", host = "https://github.com")), "unittest_branch1", - direction = c("upstream"), local_repos = NULL, fallback_branch = "not_exist", verbose = 0)), - regexp = "Available refs 'main' must include at least one of 'unittest_branch1, not_exist'" , fixed = TRUE + direction = c("upstream"), local_repos = NULL, fallback_branch = "not_exist", verbose = 0 + )), + regexp = "Available refs 'main' must include at least one of 'unittest_branch1, not_exist'", fixed = TRUE ) output <- capture.output(res <- rec_checkout_internal_deps( @@ -70,9 +69,11 @@ test_that("rec_checkout_internal_deps works (with mocking checkout)", { # dput(output) expect_equal( output, - c("Mocking checkout_repo for stageddeps.food", + c( + "Mocking checkout_repo for stageddeps.food", "Mocking checkout_repo for stageddeps.electricity", - "Mocking checkout_repo for stageddeps.elecinfra") + "Mocking checkout_repo for stageddeps.elecinfra" + ) ) # check result by comparing to ground-truth @@ -80,9 +81,11 @@ test_that("rec_checkout_internal_deps works (with mocking checkout)", { expect_setequal( res$repo, - c("openpharma/stageddeps.food", + c( + "openpharma/stageddeps.food", "openpharma/stageddeps.electricity", - "openpharma/stageddeps.elecinfra") + "openpharma/stageddeps.elecinfra" + ) ) expect_setequal( res$host, @@ -93,8 +96,8 @@ test_that("rec_checkout_internal_deps works (with mocking checkout)", { file.path(get_packages_cache_dir(), c( "openpharma_stageddeps.food_c04cb0c69b298637f12bb39ac4f17f95", "openpharma_stageddeps.electricity_d99d4ffe828b509002243d240b2f4859", - "openpharma_stageddeps.elecinfra_7300aa2e17982fff37d603654479c06d") - ) + "openpharma_stageddeps.elecinfra_7300aa2e17982fff37d603654479c06d" + )) ) expect_setequal( res$ref, @@ -108,7 +111,7 @@ test_that("rec_checkout_internal_deps works for inaccessible repos (with mocking # mock checkout_repo by copying the appropriate directory to the repo_dir directory # but stageddeps.water is not accessible - mockery::stub(rec_checkout_internal_deps, 'checkout_repo', function(repo_dir, repo_url, select_ref_rule, ...) { + mockery::stub(rec_checkout_internal_deps, "checkout_repo", function(repo_dir, repo_url, select_ref_rule, ...) { if (repo_url == "https://github.com/openpharma/stageddeps.water.git") { return(list(dir = as.character(NA), ref = as.character(NA), sha = as.character(NA), accessible = FALSE)) } @@ -130,7 +133,8 @@ test_that("rec_checkout_internal_deps works for inaccessible repos (with mocking res <- rec_checkout_internal_deps( list(list(repo = "openpharma/stageddeps.food", host = "https://github.com")), - "main", local_repos = NULL, verbose = 0, direction = "all" + "main", + local_repos = NULL, verbose = 0, direction = "all" ) # we should not see garden and water should not be accessible @@ -140,7 +144,6 @@ test_that("rec_checkout_internal_deps works for inaccessible repos (with mocking expect_equal(res$accessible, c(TRUE, TRUE, TRUE, TRUE, FALSE)) expect_equal(res$ref, c("main", "main", "main", "main", NA)) - }) test_that("get_hashed_repo_to_dir_mapping works", { @@ -168,7 +171,7 @@ test_that("copy_local_repo_to_cachedir works", { fs::dir_copy(file.path(TESTS_GIT_REPOS, "stageddeps.food"), repo_dir) git2r::checkout(repo_dir, "main") - #set config (needed for automation) + # set config (needed for automation) git2r::config(git2r::repository(repo_dir), user.name = "github.action", user.email = "gh@action.com") # add some staged, unstaged and untracked files @@ -220,8 +223,10 @@ test_that("copy_renv_profiles only copies /profiles/<>/renv.lock files", { copy_renv_profiles("from", "to") expect_equal( as.character(fs::dir_ls("to", recurse = 3)), - c("to/renv", "to/renv/profiles", "to/renv/profiles/example", - "to/renv/profiles/example/renv.lock", "to/renv/profiles/test", "to/renv/profiles/test/renv.lock") + c( + "to/renv", "to/renv/profiles", "to/renv/profiles/example", + "to/renv/profiles/example/renv.lock", "to/renv/profiles/test", "to/renv/profiles/test/renv.lock" + ) ) }) }) diff --git a/tests/testthat/test-check_set_equal.R b/tests/testthat/test-check_set_equal.R index c64d658..4fab367 100644 --- a/tests/testthat/test-check_set_equal.R +++ b/tests/testthat/test-check_set_equal.R @@ -7,15 +7,17 @@ test_that("check_set_equal returns no error if sets are equal", { test_that("check_set_equal returns error message containing the set differences", { # note the escaping of \ in the regexp expect_error(check_set_equal(c("A", "B"), c("B")), - regexp = "Sets do not agree, setdiff x \\\\ y is 'A', setdiff y \\\\ x is ''") + regexp = "Sets do not agree, setdiff x \\\\ y is 'A', setdiff y \\\\ x is ''" + ) expect_error(check_set_equal(1:5, 3:7), - regexp = "Sets do not agree, setdiff x \\\\ y is '1, 2', setdiff y \\\\ x is '6, 7'") - + regexp = "Sets do not agree, setdiff x \\\\ y is '1, 2', setdiff y \\\\ x is '6, 7'" + ) }) test_that("pre_msg appears at the start of check_set_equal error message", { expect_error(check_set_equal(1:5, 3:7, pre_msg = "This is an error. "), - regexp = "This is an error. Sets do not agree, setdiff x \\\\ y is '1, 2', setdiff y \\\\ x is '6, 7'") + regexp = "This is an error. Sets do not agree, setdiff x \\\\ y is '1, 2', setdiff y \\\\ x is '6, 7'" + ) }) diff --git a/tests/testthat/test-dependencies.R b/tests/testthat/test-dependencies.R index cb48869..5f05d00 100644 --- a/tests/testthat/test-dependencies.R +++ b/tests/testthat/test-dependencies.R @@ -5,30 +5,31 @@ local_pkgs <- c("stageddeps.elecinfra", "stageddeps.electricity", "stageddeps.fo # assumes that repo stageddeps.food is local # copies repos from TESTS_GIT_REPOS to appropriate locations in cache_dir -mock_rec_checkout_internal_deps <- function(source_dir) function(repos_to_process, ...) { - cat(paste0("Mocking rec_checkout_internal_deps", "\n")) - expect_equal(repos_to_process, list(list(repo = "openpharma/stageddeps.food", host = "https://github.com"))) - - # stageddeps.food is local - internal_deps <- data.frame( - pkg = local_pkgs, - repo = paste0("openpharma/", local_pkgs), - host = rep("https://github.com", 6), - ref = c("main", "main", "local (main)", "main", "main", "main"), - sha = rep("test", 6), - accessible = rep(TRUE, 6), - installable = rep(TRUE, 6), - stringsAsFactors = FALSE - ) %>% dplyr::mutate(cache_dir = unlist(Map(get_repo_cache_dir, repo, host, local = grepl("^local ", ref)))) - # fs::dir_copy does not seem to be vectorized (although stated in the doc) -> use Map - clear_cache() - Map(fs::dir_copy, file.path(source_dir, internal_deps$pkg), internal_deps$cache_dir) - return(internal_deps %>% dplyr::select(repo, host, cache_dir, ref, sha, accessible, installable)) +mock_rec_checkout_internal_deps <- function(source_dir) { + function(repos_to_process, ...) { + cat(paste0("Mocking rec_checkout_internal_deps", "\n")) + expect_equal(repos_to_process, list(list(repo = "openpharma/stageddeps.food", host = "https://github.com"))) + + # stageddeps.food is local + internal_deps <- data.frame( + pkg = local_pkgs, + repo = paste0("openpharma/", local_pkgs), + host = rep("https://github.com", 6), + ref = c("main", "main", "local (main)", "main", "main", "main"), + sha = rep("test", 6), + accessible = rep(TRUE, 6), + installable = rep(TRUE, 6), + stringsAsFactors = FALSE + ) %>% dplyr::mutate(cache_dir = unlist(Map(get_repo_cache_dir, repo, host, local = grepl("^local ", ref)))) + # fs::dir_copy does not seem to be vectorized (although stated in the doc) -> use Map + clear_cache() + Map(fs::dir_copy, file.path(source_dir, internal_deps$pkg), internal_deps$cache_dir) + return(internal_deps %>% dplyr::select("repo", "host", "cache_dir", "ref", "sha", "accessible", "installable")) + } } test_that("dependency_table works", { - - mockery::stub(dependency_table, 'rec_checkout_internal_deps', mock_rec_checkout_internal_deps(TESTS_GIT_REPOS)) + mockery::stub(dependency_table, "rec_checkout_internal_deps", mock_rec_checkout_internal_deps(TESTS_GIT_REPOS)) repo_dir <- tempfile("stageddeps.food") fs::dir_copy(file.path(TESTS_GIT_REPOS, "stageddeps.food"), repo_dir) @@ -36,7 +37,6 @@ test_that("dependency_table works", { git2r::remote_set_url(repo_dir, name = "origin", url = "https://github.com/openpharma/stageddeps.food.git") with_tmp_cachedir({ - expect_output( dep_table <- dependency_table(repo_dir, ref = "main"), regexp = "Mocking rec_checkout_internal_deps", fixed = TRUE @@ -49,11 +49,14 @@ test_that("dependency_table works", { expect_equal( dep_table$table, data.frame( - package_name = c("stageddeps.food", "stageddeps.elecinfra", - "stageddeps.electricity", "stageddeps.house", "stageddeps.garden", - "stageddeps.water"), + package_name = c( + "stageddeps.food", "stageddeps.elecinfra", + "stageddeps.electricity", "stageddeps.house", "stageddeps.garden", + "stageddeps.water" + ), type = factor(c("current", "upstream", "upstream", "downstream", "other", "other"), - levels = c("current", "upstream", "downstream", "other")), + levels = c("current", "upstream", "downstream", "other") + ), distance = c(0, 1, 2, 1, NA, NA), ref = c("local (main)", "main", "main", "main", "main", "main"), install_index = c(3, 1, 2, 5, 6, 4), @@ -62,11 +65,14 @@ test_that("dependency_table works", { repo = paste0("openpharma/", package_name), host = rep("https://github.com", 6), cache_dir = unlist(Map(get_repo_cache_dir, repo, host, local = grepl("^local ", ref))), - sha = rep("test", 6), + sha = rep("test", 6), accessible = rep(TRUE, 6), installable = rep(TRUE, 6) - ) %>% dplyr::select(package_name, type, distance, ref, repo, host, sha, cache_dir, accessible, installable, install_index) - + ) %>% + dplyr::select( + "package_name", "type", "distance", "ref", "repo", "host", + "sha", "cache_dir", "accessible", "installable", "install_index" + ) ) expect_output( @@ -76,7 +82,6 @@ test_that("dependency_table works", { # check direction upstream only, should not matter since yamls agree with DESCRIPTION files expect_equal(dep_table[names(dep_table) != "direction"], dep_table2[names(dep_table2) != "direction"]) }) - }) test_that("dependency_table wih local_pkgs works", { @@ -87,10 +92,11 @@ test_that("dependency_table wih local_pkgs works", { lapply(local_pkgs, function(local_pkg) { repo_dir <- file.path(copied_ecosystem, local_pkg) git2r::checkout(repo_dir, "main") - git2r::remote_set_url(repo_dir, name = "origin", + git2r::remote_set_url(repo_dir, + name = "origin", url = paste0("https://github.com/openpharma/", local_pkg, ".git") ) - #set config (needed for automation) + # set config (needed for automation) git2r::config(git2r::repository(repo_dir), user.name = "github.action", user.email = "gh@action.com") }) @@ -120,7 +126,7 @@ test_that("check_yamls_consistent works", { copied_ecosystem <- tempfile("copied_ecosystem") fs::dir_copy(TESTS_GIT_REPOS, copied_ecosystem) - mockery::stub(dependency_table, 'rec_checkout_internal_deps', mock_rec_checkout_internal_deps(copied_ecosystem)) + mockery::stub(dependency_table, "rec_checkout_internal_deps", mock_rec_checkout_internal_deps(copied_ecosystem)) with_tmp_cachedir({ # missing staged_dependencies.yaml in stageddeps.garden @@ -148,7 +154,7 @@ test_that("check_yamls_consistent works", { }) test_that("plot.dependency_structure works", { - mockery::stub(dependency_table, 'rec_checkout_internal_deps', mock_rec_checkout_internal_deps(TESTS_GIT_REPOS)) + mockery::stub(dependency_table, "rec_checkout_internal_deps", mock_rec_checkout_internal_deps(TESTS_GIT_REPOS)) repo_dir <- tempfile("stageddeps.food") fs::dir_copy(file.path(TESTS_GIT_REPOS, "stageddeps.food"), repo_dir) git2r::remote_set_url(repo_dir, name = "origin", url = "https://github.com/openpharma/stageddeps.food.git") @@ -171,17 +177,19 @@ test_that("install_deps works", { fs::dir_copy(file.path(TESTS_GIT_REPOS, "stageddeps.food"), repo_dir) git2r::checkout(repo_dir, "main") git2r::remote_set_url(repo_dir, name = "origin", url = "https://github.com/openpharma/stageddeps.food.git") - mockery::stub(dependency_table, 'rec_checkout_internal_deps', mock_rec_checkout_internal_deps(TESTS_GIT_REPOS)) + mockery::stub(dependency_table, "rec_checkout_internal_deps", mock_rec_checkout_internal_deps(TESTS_GIT_REPOS)) capture.output(dep_table <- dependency_table(repo_dir, ref = "fixgarden@main")) # capture.output to make silent - mockery::stub(install_deps, 'run_package_actions', function(pkg_actions, ...) { + mockery::stub(install_deps, "run_package_actions", function(pkg_actions, ...) { pkg_actions }) # check install_direction = "upstream" expected_result <- data.frame( - package_name = c("stageddeps.elecinfra", "stageddeps.electricity", - "stageddeps.food"), + package_name = c( + "stageddeps.elecinfra", "stageddeps.electricity", + "stageddeps.food" + ), stringsAsFactors = FALSE ) expected_result$actions <- rep(list("install"), 3) @@ -194,8 +202,10 @@ test_that("install_deps works", { # in theory may fail because topological order is not unique, # although topological order is not unique our implementation should be deterministic expected_result <- data.frame( - package_name = c("stageddeps.elecinfra", "stageddeps.electricity", - "stageddeps.food", "stageddeps.water", "stageddeps.house"), + package_name = c( + "stageddeps.elecinfra", "stageddeps.electricity", + "stageddeps.food", "stageddeps.water", "stageddeps.house" + ), stringsAsFactors = FALSE ) expected_result$actions <- rep(list("install"), 5) @@ -209,9 +219,11 @@ test_that("install_deps works", { # in theory may fail because topological order is not unique, # although topological order is not unique our implementation should be deterministic expected_result <- data.frame( - package_name = c("stageddeps.elecinfra", "stageddeps.electricity", - "stageddeps.food", "stageddeps.water", "stageddeps.house", - "stageddeps.garden"), + package_name = c( + "stageddeps.elecinfra", "stageddeps.electricity", + "stageddeps.food", "stageddeps.water", "stageddeps.house", + "stageddeps.garden" + ), stringsAsFactors = FALSE ) expected_result$actions <- rep(list("install"), 6) @@ -220,7 +232,6 @@ test_that("install_deps works", { install_deps(dep_table, dry_install = TRUE, install_direction = "all")[, c("package_name", "actions")], expected_result ) - }) test_that("check_downstream works", { @@ -229,16 +240,18 @@ test_that("check_downstream works", { git2r::checkout(repo_dir, "main") git2r::remote_set_url(repo_dir, name = "origin", url = "https://github.com/openpharma/stageddeps.food.git") - mockery::stub(dependency_table, 'rec_checkout_internal_deps', mock_rec_checkout_internal_deps(TESTS_GIT_REPOS)) + mockery::stub(dependency_table, "rec_checkout_internal_deps", mock_rec_checkout_internal_deps(TESTS_GIT_REPOS)) capture.output(dep_table <- dependency_table(repo_dir, ref = "fixgarden@main")) # capture.output to make silent - mockery::stub(check_downstream, 'run_package_actions', function(pkg_actions, ...) { + mockery::stub(check_downstream, "run_package_actions", function(pkg_actions, ...) { pkg_actions }) expected_res <- data.frame( - package_name = c("stageddeps.elecinfra", "stageddeps.electricity", - "stageddeps.food", "stageddeps.water", "stageddeps.house"), + package_name = c( + "stageddeps.elecinfra", "stageddeps.electricity", + "stageddeps.food", "stageddeps.water", "stageddeps.house" + ), stringsAsFactors = FALSE ) # workaround because adding it directly into data.frame(...) does not work @@ -257,22 +270,23 @@ test_that("check_downstream works", { }) test_that("build_check_install works", { - repo_dir <- tempfile("stageddeps.food") fs::dir_copy(file.path(TESTS_GIT_REPOS, "stageddeps.food"), repo_dir) git2r::checkout(repo_dir, "main") git2r::remote_set_url(repo_dir, name = "origin", url = "https://github.com/openpharma/stageddeps.food.git") - mockery::stub(dependency_table, 'rec_checkout_internal_deps', mock_rec_checkout_internal_deps(TESTS_GIT_REPOS)) + mockery::stub(dependency_table, "rec_checkout_internal_deps", mock_rec_checkout_internal_deps(TESTS_GIT_REPOS)) capture.output(dep_table <- dependency_table(repo_dir, ref = "fixgarden@main")) # capture.output to make silent - mockery::stub(build_check_install, 'run_package_actions', function(pkg_actions, ...) { + mockery::stub(build_check_install, "run_package_actions", function(pkg_actions, ...) { pkg_actions }) expected_res <- data.frame( - package_name = c("stageddeps.elecinfra", "stageddeps.electricity", - "stageddeps.food", "stageddeps.water", "stageddeps.house", "stageddeps.garden"), + package_name = c( + "stageddeps.elecinfra", "stageddeps.electricity", + "stageddeps.food", "stageddeps.water", "stageddeps.house", "stageddeps.garden" + ), stringsAsFactors = FALSE ) # workaround because adding it directly into data.frame(...) does not work @@ -281,7 +295,6 @@ test_that("build_check_install works", { build_check_install(dep_table)$pkg_actions[, c("package_name", "actions")], expected_res ) - }) @@ -290,8 +303,10 @@ test_that("get_all_external_deps works", { # dummy dependency_structure object deps <- list( - external = list(A = data.frame(type = c("Imports", "Suggests"), package = c("X", "Y")), - B = data.frame(type = c("Depends"), package = "Z")), + external = list( + A = data.frame(type = c("Imports", "Suggests"), package = c("X", "Y")), + B = data.frame(type = c("Depends"), package = "Z") + ), upstream_deps = list(A = "B", B = character(0)), downstream_deps = list(B = "A", character(0)) ) @@ -311,43 +326,54 @@ test_that("get_all_external_deps works", { ) - available_packages <- data.frame(Package = c("T", "U", "V", "W", "X", "Y", "Z"), - Depends = c(NA, NA, NA, "Q", "U", NA, "T"), - Imports = c(NA, NA, NA, NA, NA, "U,V", NA), - Suggests = c(NA, NA, NA, "S", NA, NA, "W"), - LinkingTo = as.character(rep(NA, 7))) + available_packages <- data.frame( + Package = c("T", "U", "V", "W", "X", "Y", "Z"), + Depends = c(NA, NA, NA, "Q", "U", NA, "T"), + Imports = c(NA, NA, NA, NA, NA, "U,V", NA), + Suggests = c(NA, NA, NA, "S", NA, NA, "W"), + LinkingTo = as.character(rep(NA, 7)) + ) # These tests rely on a deterministic topological_sort function - expect_equal(get_all_external_dependencies(x, available_packages = available_packages), - c("U", "X", "V", "Y", "T", "Z")) + expect_equal( + get_all_external_dependencies(x, available_packages = available_packages), + c("U", "X", "V", "Y", "T", "Z") + ) # test from_internal_dependencies remove suggests) results <- get_all_external_dependencies(x, available_packages = available_packages, from_internal_dependencies = c("Depends", "Imports", "LinkingTo")) expect_equal(results, c("U", "X", "T", "Z")) # only take B's dependencies - expect_equal(get_all_external_dependencies(x, - package_list = "B", - available_packages = available_packages), - c("T", "Z")) + expect_equal( + get_all_external_dependencies(x, + package_list = "B", + available_packages = available_packages + ), + c("T", "Z") + ) # test from_external_dependencies and check get warning for missing packages - expect_warning(results <- get_all_external_dependencies(x, available_packages = available_packages, - from_external_dependencies = c("Depends", "Imports", "LinkingTo", "Suggests")), - "Cannot find information about package\\(s\\) Q, S check that options\\('repos'\\) contains expected repos") + expect_warning( + results <- get_all_external_dependencies(x, + available_packages = available_packages, + from_external_dependencies = c("Depends", "Imports", "LinkingTo", "Suggests") + ), + "Cannot find information about package\\(s\\) Q, S check that options\\('repos'\\) contains expected repos" + ) # we just need Q before W, T before Z, U before X and U + V before Y expect_equal(results, c("Q", "W", "U", "X", "V", "Y", "T", "Z", "S")) # message and unsorted list if not all of Depends, Imports and LinkingTo are `from_external_dependencies` - expect_message(results <- get_all_external_dependencies(x, - package_list = "B", - available_packages = available_packages, - from_external_dependencies = c("Depends", "Imports")), - regexp = "Packages will not be ordered as this requires") + expect_message(results <- get_all_external_dependencies(x, + package_list = "B", + available_packages = available_packages, + from_external_dependencies = c("Depends", "Imports") + ), + regexp = "Packages will not be ordered as this requires" + ) expect_equal(sort(results), c("T", "Z")) - }) - diff --git a/tests/testthat/test-dependencies_helper.R b/tests/testthat/test-dependencies_helper.R index 74d2340..6b61789 100644 --- a/tests/testthat/test-dependencies_helper.R +++ b/tests/testthat/test-dependencies_helper.R @@ -3,8 +3,10 @@ test_that("get_true_deps_graph works", { # take out "stageddeps.water", so it will be treated like an external # dependency (i.e. not appear in the dep graph) pkgs_df <- data.frame( - package_name = c("stageddeps.elecinfra", "stageddeps.electricity", "stageddeps.food", - "stageddeps.house", "stageddeps.garden"), + package_name = c( + "stageddeps.elecinfra", "stageddeps.electricity", "stageddeps.food", + "stageddeps.house", "stageddeps.garden" + ), dummy_col = 11:15, stringsAsFactors = FALSE ) %>% dplyr::mutate(cache_dir = file.path(TESTS_GIT_REPOS, package_name)) @@ -16,15 +18,21 @@ test_that("get_true_deps_graph works", { external = list( stageddeps.elecinfra = data.frame(type = "Suggests", package = "testthat", version = ">= 2.1.0"), stageddeps.electricity = data.frame(type = "Suggests", package = "testthat", version = ">= 2.1.0"), - stageddeps.food = data.frame(type = c("Imports", "Imports", "Suggests"), - package = c("desc", "SummarizedExperiment", "testthat"), - version = c("*", "*", ">= 2.1.0")), - stageddeps.house = data.frame(type = c("Imports", "Suggests"), - package = c("stageddeps.water", "testthat"), # water treated as external, see above - version = c("*", ">= 2.1.0")), - stageddeps.garden = data.frame(type = c("Imports", "Suggests"), - package = c("stageddeps.water", "testthat"), - version = c("*", ">= 2.1.0")) + stageddeps.food = data.frame( + type = c("Imports", "Imports", "Suggests"), + package = c("desc", "SummarizedExperiment", "testthat"), + version = c("*", "*", ">= 2.1.0") + ), + stageddeps.house = data.frame( + type = c("Imports", "Suggests"), + package = c("stageddeps.water", "testthat"), # water treated as external, see above + version = c("*", ">= 2.1.0") + ), + stageddeps.garden = data.frame( + type = c("Imports", "Suggests"), + package = c("stageddeps.water", "testthat"), + version = c("*", ">= 2.1.0") + ) ), upstream_deps = list( stageddeps.elecinfra = character(0), @@ -42,7 +50,6 @@ test_that("get_true_deps_graph works", { ) ) ) - }) # get_local_pkgs_from_config ---- @@ -75,24 +82,30 @@ test_that("add_project_to_local_repos works", { project <- file.path(TESTS_GIT_REPOS, "stageddeps.food") expect_equal( add_project_to_local_repos(project, local_repos = NULL), - data.frame(repo = "openpharma/stageddeps.food", host = "https://github.com", - directory = normalize_path(project), - stringsAsFactors = FALSE) + data.frame( + repo = "openpharma/stageddeps.food", host = "https://github.com", + directory = normalize_path(project), + stringsAsFactors = FALSE + ) ) expect_equal( add_project_to_local_repos( project, - local_repos = data.frame(repo = "openpharma/stageddeps.electricity", host = "https://github.com", - directory = normalize_path(file.path(TESTS_GIT_REPOS, "stageddeps.electricity")), stringsAsFactors = FALSE) + local_repos = data.frame( + repo = "openpharma/stageddeps.electricity", host = "https://github.com", + directory = normalize_path(file.path(TESTS_GIT_REPOS, "stageddeps.electricity")), stringsAsFactors = FALSE + ) ), - data.frame(repo = c("openpharma/stageddeps.electricity", "openpharma/stageddeps.food"), - host = c("https://github.com", "https://github.com"), - directory = c( - normalize_path(file.path(TESTS_GIT_REPOS, "stageddeps.electricity")), - normalize_path(project) - ), - stringsAsFactors = FALSE) + data.frame( + repo = c("openpharma/stageddeps.electricity", "openpharma/stageddeps.food"), + host = c("https://github.com", "https://github.com"), + directory = c( + normalize_path(file.path(TESTS_GIT_REPOS, "stageddeps.electricity")), + normalize_path(project) + ), + stringsAsFactors = FALSE + ) ) }) @@ -125,13 +138,17 @@ test_that("yaml_from_dep_table works", { test_that("parse_remote_project works", { # repo@host - expect_equal(parse_remote_project("x@y"), - list(repo = "x", host = "y")) + expect_equal( + parse_remote_project("x@y"), + list(repo = "x", host = "y") + ) # missing host uses default - expect_equal(parse_remote_project("x"), - list(repo = "x", host = "https://github.com")) + expect_equal( + parse_remote_project("x"), + list(repo = "x", host = "https://github.com") + ) # more than 1 @ throws error expect_error(parse_remote_project("x@y@z")) @@ -144,7 +161,7 @@ test_that("parse_remote_project works", { # run_package_actions ---- test_that("run_package_actions works", { - mockery::stub(run_package_actions, 'install_repo_add_sha', function(cache_dir, ...) { + mockery::stub(run_package_actions, "install_repo_add_sha", function(cache_dir, ...) { cat(paste0("Mocking install_repo_add_sha for ", cache_dir, "\n")) }) @@ -154,8 +171,10 @@ test_that("run_package_actions works", { data.frame( cache_dir = file.path(TESTS_GIT_REPOS, c("stageddeps.elecinfra", "stageddeps.electricity")), actions = c("install", "install"), - sha = c(get_short_sha(file.path(TESTS_GIT_REPOS, c("stageddeps.elecinfra"))), - get_short_sha(file.path(TESTS_GIT_REPOS, c("stageddeps.electricity")))), + sha = c( + get_short_sha(file.path(TESTS_GIT_REPOS, c("stageddeps.elecinfra"))), + get_short_sha(file.path(TESTS_GIT_REPOS, c("stageddeps.electricity"))) + ), installable = c(TRUE, TRUE), stringsAsFactors = FALSE ), @@ -167,23 +186,21 @@ test_that("run_package_actions works", { c( paste0("Mocking install_repo_add_sha for ", file.path(TESTS_GIT_REPOS, "stageddeps.elecinfra")), paste0("Mocking install_repo_add_sha for ", file.path(TESTS_GIT_REPOS, "stageddeps.electricity")) - ) ) - #invalid sha + # invalid sha expect_error( run_package_actions( data.frame( cache_dir = file.path(TESTS_GIT_REPOS, c("stageddeps.elecinfra", "stageddeps.electricity")), actions = c("install", "install"), - sha = c("xxx","yyy"), + sha = c("xxx", "yyy"), installable = c(TRUE, TRUE), stringsAsFactors = FALSE ), install_external_deps = FALSE ) - ) # if installable is FALSE then package is skipped @@ -192,8 +209,10 @@ test_that("run_package_actions works", { data.frame( cache_dir = file.path(TESTS_GIT_REPOS, c("stageddeps.elecinfra", "stageddeps.electricity")), actions = c("install", "install"), - sha = c(get_short_sha(file.path(TESTS_GIT_REPOS, c("stageddeps.elecinfra"))), - get_short_sha(file.path(TESTS_GIT_REPOS, c("stageddeps.electricity")))), + sha = c( + get_short_sha(file.path(TESTS_GIT_REPOS, c("stageddeps.elecinfra"))), + get_short_sha(file.path(TESTS_GIT_REPOS, c("stageddeps.electricity"))) + ), installable = c(TRUE, FALSE), stringsAsFactors = FALSE ), @@ -205,7 +224,6 @@ test_that("run_package_actions works", { output, # not installing electricity paste0("Mocking install_repo_add_sha for ", file.path(TESTS_GIT_REPOS, "stageddeps.elecinfra")) ) - }) # parse_deps_table ---- diff --git a/tests/testthat/test-get_descendants_distance.R b/tests/testthat/test-get_descendants_distance.R index 5137b5a..ff69ce5 100644 --- a/tests/testthat/test-get_descendants_distance.R +++ b/tests/testthat/test-get_descendants_distance.R @@ -1,32 +1,31 @@ test_that("get_descendants_distance with no descendants returns dataframe with 0 rows", { - expect_equal(nrow(get_descendants_distance(NULL, starting_node = "A")), 0) expect_equal(nrow(get_descendants_distance(list(), starting_node = "A")), 0) - expect_equal(nrow(get_descendants_distance(list(B=list("A")), starting_node = "A")), 0) - + expect_equal(nrow(get_descendants_distance(list(B = list("A")), starting_node = "A")), 0) }) test_that("get_descendants_distance takes minimum distance between two nodes", { - - parents_to_children <- list(A = list("C"), - B = list("A", "C"), - C = list()) + parents_to_children <- list( + A = list("C"), + B = list("A", "C"), + C = list() + ) result <- get_descendants_distance(parents_to_children, starting_node = "B") expect_equal(result$id, c("A", "C")) expect_equal(result$distance, c(1, 1)) - }) test_that("get_descendants_distance only includes descendants", { - - parents_to_children <- list(A = list("C"), - B = list("A", "C"), - C = list(), - D = list("E"), - E = list()) + parents_to_children <- list( + A = list("C"), + B = list("A", "C"), + C = list(), + D = list("E"), + E = list() + ) result <- get_descendants_distance(parents_to_children, starting_node = "B") expect_equal(result$id, c("A", "C")) expect_equal(result$distance, c(1, 1)) @@ -34,30 +33,31 @@ test_that("get_descendants_distance only includes descendants", { result <- get_descendants_distance(parents_to_children, starting_node = "D") expect_equal(result$id, "E") expect_equal(result$distance, 1) - }) test_that("get_descendants_distance handles minimum distances greater than 1", { - - parents_to_children <- list(A = list("B"), - B = list("C", "D"), - C = list("E", "F"), - D = list("G"), - E = list("F", "G"), - F = list(), - G = list()) + parents_to_children <- list( + A = list("B"), + B = list("C", "D"), + C = list("E", "F"), + D = list("G"), + E = list("F", "G"), + F = list(), + G = list() + ) result <- get_descendants_distance(parents_to_children, starting_node = "A") expect_equal(result$id, c("B", "C", "D", "E", "F", "G")) expect_equal(result$distance, c(1, 2, 2, 3, 3, 3)) - }) test_that("get_descendants_distance node names can include symbols", { - parents_to_children <- list(`A @ A` = list("C / D"), - `B > C` = list("A @ A", "C / D"), - `C / D` = list()) + parents_to_children <- list( + `A @ A` = list("C / D"), + `B > C` = list("A @ A", "C / D"), + `C / D` = list() + ) result <- get_descendants_distance(parents_to_children, starting_node = "B > C") expect_equal(result$id, c("A @ A", "C / D")) diff --git a/tests/testthat/test-git_tools.R b/tests/testthat/test-git_tools.R index e8372d5..cf91830 100644 --- a/tests/testthat/test-git_tools.R +++ b/tests/testthat/test-git_tools.R @@ -3,13 +3,14 @@ # ---- get_authtoken_envvar ---- test_that("get_authtoken_envvar works", { withr::with_options(list( - staged.dependencies.token_mapping = list("https://github.com" = "GITHUB_PAT")), { - expect_error( - get_authtoken_envvar("github.com"), - regexp = "unknown host", fixed = TRUE - ) - expect_equal(get_authtoken_envvar("https://github.com"), "GITHUB_PAT") - }) + staged.dependencies.token_mapping = list("https://github.com" = "GITHUB_PAT") + ), { + expect_error( + get_authtoken_envvar("github.com"), + regexp = "unknown host", fixed = TRUE + ) + expect_equal(get_authtoken_envvar("https://github.com"), "GITHUB_PAT") + }) }) # ---- get_repo_url ---- @@ -22,14 +23,15 @@ test_that("get_repo_url works", { # ---- checkout_repo ---- test_that("checkout_repo works (requires Internet access)", { - expect_silent({ # check error when dir is not a git repo existing_dir <- tempfile() dir.create(existing_dir) expect_error( checkout_repo(existing_dir, "https://github.com/openpharma/stageddeps.water.git", - function(...) structure("main", type = "branch"), token_envvar = NULL), + function(...) structure("main", type = "branch"), + token_envvar = NULL + ), regex = "not in a git repository", fixed = TRUE ) unlink(existing_dir, recursive = TRUE) @@ -38,13 +40,16 @@ test_that("checkout_repo works (requires Internet access)", { repo_dir <- tempfile() expect_error( checkout_repo(repo_dir, "https://github.com/openpharma/stageddeps.water.git", - function(...) structure("inexistantBranch", type = "branch"), - token_envvar = NULL, must_work = TRUE), + function(...) structure("inexistantBranch", type = "branch"), + token_envvar = NULL, must_work = TRUE + ), regex = "ref inexistantBranch is unavailable for this repo", fixed = TRUE ) # checkout existing branch x <- checkout_repo(repo_dir, "https://github.com/openpharma/stageddeps.water.git", - function(...) structure("main", type = "branch"), token_envvar = NULL) + function(...) structure("main", type = "branch"), + token_envvar = NULL + ) # do not test SHA equality, just that it is there x$sha <- "test" expect_equal( @@ -57,11 +62,11 @@ test_that("checkout_repo works (requires Internet access)", { withr::with_envvar(list(INCORRECT_TOKEN = "adfs"), { expect_error( checkout_repo(repo_dir, "https://github.com/inexistentOrg/inexistentRepo.git", - function(...) structure("main", type = "branch"), - token_envvar = "INCORRECT_TOKEN", must_work = TRUE), + function(...) structure("main", type = "branch"), + token_envvar = "INCORRECT_TOKEN", must_work = TRUE + ), regexp = "Bad credentials", fixed = TRUE ) }) }) - }) diff --git a/tests/testthat/test-git_tools_mocking.R b/tests/testthat/test-git_tools_mocking.R index daa6e53..b0da1cb 100644 --- a/tests/testthat/test-git_tools_mocking.R +++ b/tests/testthat/test-git_tools_mocking.R @@ -7,7 +7,7 @@ test_that("checkout_repo with mocking works", { # mock git clone # delete mock function with rm(list = c("checkout_repo")) - mockery::stub(checkout_repo, 'git2r::clone', function(url, local_path, ...) { + mockery::stub(checkout_repo, "git2r::clone", function(url, local_path, ...) { print("Mocking git2r::clone") existing_repo_dir <- file.path(TESTS_GIT_REPOS, basename(local_path)) stopifnot(dir.exists(existing_repo_dir)) @@ -21,12 +21,12 @@ test_that("checkout_repo with mocking works", { git2r::repository(local_path) }) - mockery::stub(checkout_repo, 'git2r::fetch', function(url, local_path, ...) { + mockery::stub(checkout_repo, "git2r::fetch", function(url, local_path, ...) { print("Mocking git2r::fetch") invisible(NULL) }) - mockery::stub(checkout_repo, 'get_remote_name', function(...) "origin") + mockery::stub(checkout_repo, "get_remote_name", function(...) "origin") with_tmp_cachedir({ repo_dir <- file.path(tempfile(), "stageddeps.food") @@ -34,8 +34,10 @@ test_that("checkout_repo with mocking works", { # check that clone is called expect_output( checkout_repo(repo_dir, - "REPLACED/stageddeps.food.git", - function(...) structure("unittest_branch1", type = "branch"), token_envvar = NULL), + "REPLACED/stageddeps.food.git", + function(...) structure("unittest_branch1", type = "branch"), + token_envvar = NULL + ), regexp = "Mocking git2r::clone", fixed = TRUE ) @@ -43,8 +45,10 @@ test_that("checkout_repo with mocking works", { expect_output( expect_error( checkout_repo(repo_dir, - "REPLACED/stageddeps.food.git", - function(...) structure("inexistantBranch", type = "branch"), token_envvar = NULL), + "REPLACED/stageddeps.food.git", + function(...) structure("inexistantBranch", type = "branch"), + token_envvar = NULL + ), regexp = "ref inexistantBranch is unavailable for this repo", fixed = TRUE ), regexp = "Mocking git2r::fetch", fixed = TRUE @@ -52,14 +56,15 @@ test_that("checkout_repo with mocking works", { # checkout an existing branch (after fetching) expect_output( checkout_repo(repo_dir, - "REPLACED/stageddeps.food.git", - function(...) structure("unittest_branch2", type = "branch"), token_envvar = NULL), + "REPLACED/stageddeps.food.git", + function(...) structure("unittest_branch2", type = "branch"), + token_envvar = NULL + ), regexp = "Mocking git2r::fetch", fixed = TRUE ) unlink(repo_dir, recursive = TRUE) }) - }) # ---- check_only_remote_branches ---- @@ -79,26 +84,22 @@ test_that("check_only_remote_branches works", { }) -test_that("get_remote_name provides remote name of repo",{ - - mockery::stub(get_remote_name, 'git2r::remote_url', function(git_repo, remote){ +test_that("get_remote_name provides remote name of repo", { + mockery::stub(get_remote_name, "git2r::remote_url", function(git_repo, remote) { switch(remote, - A = "git@ssh.github.com:x/y.git", - B = "git@github.com:w/v.git", - C = "https://github.com/k/l/m", - D = "https://github.com/a/b.git", - origin = "https://github.com/xxx/c.git" + A = "git@ssh.github.com:x/y.git", + B = "git@github.com:w/v.git", + C = "https://github.com/k/l/m", + D = "https://github.com/a/b.git", + origin = "https://github.com/xxx/c.git" ) }) - mockery::stub(get_remote_name, 'git2r::remotes', function(git_repo) c("origin", "A", "B", "C", "D")) + mockery::stub(get_remote_name, "git2r::remotes", function(git_repo) c("origin", "A", "B", "C", "D")) expect_equal(get_remote_name(".", "https://github.com/x/y.git"), "A") expect_equal(get_remote_name(".", "https://github.com/w/v.git"), "B") expect_equal(get_remote_name(".", "https://github.com/k/l/m.git"), "C") expect_equal(get_remote_name(".", "https://github.com/a/b.git"), "D") expect_equal(get_remote_name(".", "https://other.git"), "origin") - - }) - diff --git a/tests/testthat/test-graph_methods.R b/tests/testthat/test-graph_methods.R index 5487aec..af2bce0 100644 --- a/tests/testthat/test-graph_methods.R +++ b/tests/testthat/test-graph_methods.R @@ -1,6 +1,5 @@ # topological sort ---- test_that("topological sort throws error if circular relationship", { - expect_error(topological_sort( list(n1 = "n3", n2 = "n2", n3 = c("")) )) @@ -12,7 +11,6 @@ test_that("topological sort throws error if circular relationship", { expect_error(topological_sort( list(n1 = "n2", n2 = "n3", n3 = c("n4", "n1"), n4 = c()) )) - }) test_that("topological sort correctly sorts graph with no branching", { diff --git a/tests/testthat/test-ref_strategy.R b/tests/testthat/test-ref_strategy.R index 92f5aac..90a10c4 100644 --- a/tests/testthat/test-ref_strategy.R +++ b/tests/testthat/test-ref_strategy.R @@ -19,8 +19,7 @@ test_that("infer_ref_from_branch works", { unlink(repo_dir, recursive = TRUE) }) -test_that("check_ref_consistency works" , { - +test_that("check_ref_consistency works", { repo_dir <- tempfile("stageddeps.food") fs::dir_copy(file.path(TESTS_GIT_REPOS, "stageddeps.food"), repo_dir) git2r::checkout(repo_dir, "main") @@ -65,9 +64,13 @@ test_that("determine_ref works", { expect_equal( determine_ref( "fix1@feature1@devel", - data.frame(ref = c("main", "devel", "feature1", "feature1@devel", - "fix1@feature1@devel", "fix1"), - type = "branch") + data.frame( + ref = c( + "main", "devel", "feature1", "feature1@devel", + "fix1@feature1@devel", "fix1" + ), + type = "branch" + ) ), structure("fix1@feature1@devel", type = "branch") ) @@ -150,14 +153,15 @@ test_that("determine_ref works", { expect_equal( determine_ref( "fix1#feature1#devel", - data.frame(ref = c("main", "devel", "feature1", "feature1#devel", - "fix1@feature1@devel", "fix1"), - type = "branch"), + data.frame( + ref = c( + "main", "devel", "feature1", "feature1#devel", + "fix1@feature1@devel", "fix1" + ), + type = "branch" + ), branch_sep = "#" ), structure("feature1#devel", type = "branch") ) - - }) - diff --git a/tests/testthat/test-renv.R b/tests/testthat/test-renv.R index afa590a..99030f1 100644 --- a/tests/testthat/test-renv.R +++ b/tests/testthat/test-renv.R @@ -60,7 +60,7 @@ test_that("get_renv_lock_from_repo_dir returns json lockfile from non NULL profi }) }) -test_that("get_renv_lock_from_repo_dir returns NULL if no lockfile" , { +test_that("get_renv_lock_from_repo_dir returns NULL if no lockfile", { withr::with_tempdir({ expect_null(get_renv_lock_from_repo_dir(".")) expect_null(get_renv_lock_from_repo_dir(".", renv_profile = "test")) diff --git a/tests/testthat/test-utils.R b/tests/testthat/test-utils.R index 52f2e16..a768882 100644 --- a/tests/testthat/test-utils.R +++ b/tests/testthat/test-utils.R @@ -2,17 +2,23 @@ test_that("cbind_handle_empty works", { # when second df is empty expect_equal( cbind_handle_empty(data.frame(col1 = character(0), col2 = character(0), stringsAsFactors = FALSE), - col3 = "hello3", col4 = "hello4"), - data.frame(col1 = character(0), col2 = character(0), col3 = character(0), col4 = character(0), - stringsAsFactors = FALSE) + col3 = "hello3", col4 = "hello4" + ), + data.frame( + col1 = character(0), col2 = character(0), col3 = character(0), col4 = character(0), + stringsAsFactors = FALSE + ) ) # when second df is non-empty expect_equal( cbind_handle_empty(data.frame(col1 = c("h1", "h11"), col2 = c("h2", "h22"), stringsAsFactors = FALSE), - col3 = "hello3", col4 = "hello4"), - data.frame(col1 = c("h1", "h11"), col2 = c("h2", "h22"), col3 = c("hello3", "hello3"), col4 = c("hello4", "hello4"), - stringsAsFactors = FALSE) + col3 = "hello3", col4 = "hello4" + ), + data.frame( + col1 = c("h1", "h11"), col2 = c("h2", "h22"), col3 = c("hello3", "hello3"), col4 = c("hello4", "hello4"), + stringsAsFactors = FALSE + ) ) }) diff --git a/tests/testthat/test-validate_yaml.R b/tests/testthat/test-validate_yaml.R index 2b56c4b..26ec5ca 100644 --- a/tests/testthat/test-validate_yaml.R +++ b/tests/testthat/test-validate_yaml.R @@ -1,6 +1,5 @@ #---- Valid yaml ---- test_that("staged dep yaml without dependencies is valid ", { - text <- "--- downstream_repos: @@ -14,7 +13,6 @@ test_that("staged dep yaml without dependencies is valid ", { }) test_that("staged dep yaml allows additional fields beyond those required", { - text <- "--- downstream_repos: - repo: test2/test @@ -38,7 +36,6 @@ test_that("staged dep yaml allows additional fields beyond those required", { #---- Invalid yaml ---- test_that("empty staged dep yaml file throws error", { - text <- "--- " expect_error( @@ -55,7 +52,6 @@ test_that("empty staged dep yaml file throws error", { }) test_that("staged dep yaml file missing expected fields throws error", { - text <- "--- hello " @@ -77,7 +73,6 @@ test_that("staged dep yaml file missing expected fields throws error", { }) test_that("staged dep yaml file without current_repo content throws error", { - text <- "--- downstream_repos: - repo: test2/test @@ -94,7 +89,6 @@ test_that("staged dep yaml file without current_repo content throws error", { }) test_that("staged dep yaml file with current_repo as array throws error", { - text <- "--- upstream_repos: downstream_repos: @@ -109,7 +103,6 @@ test_that("staged dep yaml file with current_repo as array throws error", { }) test_that("staged dep yaml file cannot contain non-character values", { - text <- "--- upstream_repos: downstream_repos: @@ -168,7 +161,6 @@ test_that("staged dep yaml file cannot contain non-character values", { }) test_that("staged dep yaml file missing repo or host throws error", { - text <- "--- upstream_repos: downstream_repos: @@ -201,7 +193,6 @@ test_that("staged dep yaml file missing repo or host throws error", { }) test_that("staged dep yaml with nesting/naming inside repo or host throws an error", { - text <- "--- downstream_repos: @@ -271,5 +262,4 @@ test_that("staged dep yaml with nesting/naming inside repo or host throws an err validate_staged_deps_yaml(yaml::read_yaml(text = text)), regexp = "File invalid, field downstream_repos must have non-array character values repo, host" ) - })