From d3f47a7200506cdbb3d77036418dd93c026eb568 Mon Sep 17 00:00:00 2001 From: Maciej Banas Date: Mon, 23 Dec 2024 13:27:11 +0000 Subject: [PATCH] Add parameter to control error when wrong repos/orgs are passed. --- DESCRIPTION | 2 +- NEWS.md | 1 + R/GitHost.R | 56 +++++++++---- R/GitHostGitHub.R | 6 +- R/GitHostGitLab.R | 6 +- R/GitStats.R | 12 ++- R/gitstats_functions.R | 79 ----------------- R/set_host.R | 84 +++++++++++++++++++ inst/set_hosts.R | 14 ++++ man/set_github_host.Rd | 8 +- man/set_gitlab_host.Rd | 8 +- tests/testthat/_snaps/set_host.md | 14 ++++ tests/testthat/test-02-get_commits-GitStats.R | 4 +- tests/testthat/test-helpers.R | 4 +- tests/testthat/test-set_host.R | 13 +++ vignettes/get_repos_with_code.Rmd | 2 +- 16 files changed, 199 insertions(+), 114 deletions(-) create mode 100644 R/set_host.R create mode 100644 inst/set_hosts.R diff --git a/DESCRIPTION b/DESCRIPTION index b6e5fb1..07993a2 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: GitStats Title: Standardized Git Repository Data -Version: 2.1.2.9004 +Version: 2.1.2.9005 Authors@R: c( person(given = "Maciej", family = "Banas", email = "banasmaciek@gmail.com", role = c("aut", "cre")), person(given = "Kamil", family = "Koziej", email = "koziej.k@gmail.com", role = "aut"), diff --git a/NEWS.md b/NEWS.md index 6217850..d81d3c3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,6 +8,7 @@ - changing name of the `time_interval` parameter to `time_aggregation`, - adding `yearly` aggregation to `time_aggregation` parameter, - changing basic input from `GitStats` to `commits_data` object which allows to build workflow in one pipeline (`create_gitstats() |> set_*_host() |> get_commits() |> get_commits_stats()`). +- Add `.show_error` parameter to the `set_*_host()` functins to control if error should pop up when wrong input is passed ([#547](https://github.com/r-world-devs/GitStats/issues/547)). ## Fixes: diff --git a/R/GitHost.R b/R/GitHost.R index d373f1c..71cd508 100644 --- a/R/GitHost.R +++ b/R/GitHost.R @@ -17,7 +17,8 @@ GitHost <- R6::R6Class( repos = NA, token = NA, host = NA, - verbose = NA) { + verbose = NA, + .error = TRUE) { private$set_api_url(host) private$set_web_url(host) private$set_endpoints() @@ -36,7 +37,8 @@ GitHost <- R6::R6Class( private$set_orgs_and_repos( orgs = orgs, repos = repos, - verbose = verbose + verbose = verbose, + .error = .error ) }, @@ -413,18 +415,20 @@ GitHost <- R6::R6Class( }, # Set organization or repositories - set_orgs_and_repos = function(orgs, repos, verbose) { + set_orgs_and_repos = function(orgs, repos, verbose, .error) { if (!private$scan_all) { if (!is.null(orgs)) { private$orgs <- private$check_organizations( orgs = orgs, - verbose = verbose + verbose = verbose, + .error = .error ) } if (!is.null(repos)) { repos <- private$check_repositories( repos = repos, - verbose = verbose + verbose = verbose, + .error = .error ) private$repos_fullnames <- repos orgs_repos <- private$extract_repos_and_orgs(private$repos_fullnames) @@ -435,7 +439,7 @@ GitHost <- R6::R6Class( }, # Check if repositories exist - check_repositories = function(repos, verbose) { + check_repositories = function(repos, verbose, .error) { if (verbose) { cli::cli_alert_info(cli::col_grey("Checking repositories...")) } @@ -443,7 +447,9 @@ GitHost <- R6::R6Class( repo_endpoint <- glue::glue("{private$endpoints$repositories}/{repo}") check <- private$check_endpoint( endpoint = repo_endpoint, - type = "Repository" + type = "Repository", + verbose = verbose, + .error = .error ) if (!check) { repo <- NULL @@ -459,7 +465,7 @@ GitHost <- R6::R6Class( }, # Check if organizations exist - check_organizations = function(orgs, verbose) { + check_organizations = function(orgs, verbose, .error) { if (verbose) { cli::cli_alert_info(cli::col_grey("Checking organizations...")) } @@ -467,7 +473,9 @@ GitHost <- R6::R6Class( org_endpoint <- glue::glue("{private$endpoints$orgs}/{org}") check <- private$check_endpoint( endpoint = org_endpoint, - type = "Organization" + type = "Organization", + verbose = verbose, + .error = .error ) if (!check) { org <- NULL @@ -483,7 +491,7 @@ GitHost <- R6::R6Class( }, # Check whether the endpoint exists. - check_endpoint = function(endpoint, type) { + check_endpoint = function(endpoint, type, verbose, .error) { check <- TRUE tryCatch( { @@ -491,17 +499,29 @@ GitHost <- R6::R6Class( }, error = function(e) { if (grepl("404", e)) { - cli::cli_abort( - c( - "x" = "{type} you provided does not exist or its name was passed + if (.error) { + cli::cli_abort( + c( + "x" = "{type} you provided does not exist or its name was passed in a wrong way: {cli::col_red({utils::URLdecode(endpoint)})}", - "!" = "Please type your {tolower(type)} name as you see it in + "!" = "Please type your {tolower(type)} name as you see it in web URL.", - "i" = "E.g. do not use spaces. {type} names as you see on the + "i" = "E.g. do not use spaces. {type} names as you see on the page may differ from their web 'address'." - ), - call = NULL - ) + ), + call = NULL + ) + } else { + if (verbose) { + cli::cli_alert_warning( + cli::col_yellow( + "{type} you provided does not exist: {cli::col_red({utils::URLdecode(endpoint)})}" + ) + ) + } + check <<- FALSE + } + } } ) diff --git a/R/GitHostGitHub.R b/R/GitHostGitHub.R index f0ac14f..29463b4 100644 --- a/R/GitHostGitHub.R +++ b/R/GitHostGitHub.R @@ -7,12 +7,14 @@ GitHostGitHub <- R6::R6Class( repos = NA, token = NA, host = NA, - verbose = NA) { + verbose = NA, + .error = TRUE) { super$initialize(orgs = orgs, repos = repos, token = token, host = host, - verbose = verbose) + verbose = verbose, + .error = .error) if (verbose) { cli::cli_alert_success("Set connection to GitHub.") } diff --git a/R/GitHostGitLab.R b/R/GitHostGitLab.R index 4f2f095..39a28c1 100644 --- a/R/GitHostGitLab.R +++ b/R/GitHostGitLab.R @@ -6,7 +6,8 @@ GitHostGitLab <- R6::R6Class("GitHostGitLab", repos = NA, token = NA, host = NA, - verbose = NA) { + verbose = NA, + .error = TRUE) { repos <- if (!is.null(repos)) { url_encode(repos) } @@ -17,7 +18,8 @@ GitHostGitLab <- R6::R6Class("GitHostGitLab", repos = repos, token = token, host = host, - verbose = verbose) + verbose = verbose, + .error = .error) if (verbose) { cli::cli_alert_success("Set connection to GitLab.") } diff --git a/R/GitStats.R b/R/GitStats.R index b4fa288..bc8c91b 100644 --- a/R/GitStats.R +++ b/R/GitStats.R @@ -8,14 +8,16 @@ GitStats <- R6::R6Class( token = NULL, orgs = NULL, repos = NULL, - verbose = TRUE) { + verbose = TRUE, + .show_error = TRUE) { new_host <- NULL new_host <- GitHostGitHub$new( orgs = orgs, repos = repos, token = token, host = host, - verbose = verbose + verbose = verbose, + .error = .show_error ) private$add_new_host(new_host) }, @@ -24,14 +26,16 @@ GitStats <- R6::R6Class( token = NULL, orgs = NULL, repos = NULL, - verbose = TRUE) { + verbose = TRUE, + .show_error = TRUE) { new_host <- NULL new_host <- GitHostGitLab$new( orgs = orgs, repos = repos, token = token, host = host, - verbose = verbose + verbose = verbose, + .error = .show_error ) private$add_new_host(new_host) }, diff --git a/R/gitstats_functions.R b/R/gitstats_functions.R index e38fce1..0397c07 100644 --- a/R/gitstats_functions.R +++ b/R/gitstats_functions.R @@ -8,85 +8,6 @@ create_gitstats <- function() { GitStats$new() } -#' @title Set GitHub host -#' @name set_github_host -#' @param gitstats A GitStats object. -#' @param host A character, optional, URL name of the host. If not passed, a -#' public host will be used. -#' @param token A token. -#' @param orgs An optional character vector of organisations. If you pass it, -#' `repos` parameter should stay `NULL`. -#' @param repos An optional character vector of repositories full names -#' (organization and repository name, e.g. "r-world-devs/GitStats"). If you -#' pass it, `orgs` parameter should stay `NULL`. -#' @param verbose A logical, `TRUE` by default. If `FALSE` messages and printing -#' output is switched off. -#' @details If you do not define `orgs` and `repos`, `GitStats` will be set to -#' scan whole Git platform (such as enterprise version of GitHub or GitLab), -#' unless it is a public platform. In case of a public one (like GitHub) you -#' need to define `orgs` or `repos` as scanning through all organizations may -#' take large amount of time. -#' @return A `GitStats` object with added information on host. -#' @examples -#' \dontrun{ -#' my_gitstats <- create_gitstats() %>% -#' set_github_host( -#' orgs = c("r-world-devs", "openpharma", "pharmaverse") -#' ) -#' } -#' @export -set_github_host <- function(gitstats, - host = NULL, - token = NULL, - orgs = NULL, - repos = NULL, - verbose = is_verbose(gitstats)) { - gitstats$set_github_host( - host = host, - token = token, - orgs = orgs, - repos = repos, - verbose = verbose - ) - - return(invisible(gitstats)) -} - -#' @title Set GitLab host -#' @name set_gitlab_host -#' @inheritParams set_github_host -#' @details If you do not define `orgs` and `repos`, `GitStats` will be set to -#' scan whole Git platform (such as enterprise version of GitHub or GitLab), -#' unless it is a public platform. In case of a public one (like GitHub) you -#' need to define `orgs` or `repos` as scanning through all organizations may -#' take large amount of time. -#' @return A `GitStats` object with added information on host. -#' @examples -#' \dontrun{ -#' my_gitstats <- create_gitstats() %>% -#' set_gitlab_host( -#' token = Sys.getenv("GITLAB_PAT_PUBLIC"), -#' orgs = "mbtests" -#' ) -#' } -#' @export -set_gitlab_host <- function(gitstats, - host = NULL, - token = NULL, - orgs = NULL, - repos = NULL, - verbose = is_verbose(gitstats)) { - gitstats$set_gitlab_host( - host = host, - token = token, - orgs = orgs, - repos = repos, - verbose = verbose - ) - - return(invisible(gitstats)) -} - #' @title Get data on repositories #' @name get_repos #' @description Pulls data on all repositories for an organization, individual diff --git a/R/set_host.R b/R/set_host.R new file mode 100644 index 0000000..9bab0d3 --- /dev/null +++ b/R/set_host.R @@ -0,0 +1,84 @@ +#' @title Set GitHub host +#' @name set_github_host +#' @param gitstats A GitStats object. +#' @param host A character, optional, URL name of the host. If not passed, a +#' public host will be used. +#' @param token A token. +#' @param orgs An optional character vector of organisations. If you pass it, +#' `repos` parameter should stay `NULL`. +#' @param repos An optional character vector of repositories full names +#' (organization and repository name, e.g. "r-world-devs/GitStats"). If you +#' pass it, `orgs` parameter should stay `NULL`. +#' @param verbose A logical, `TRUE` by default. If `FALSE` messages and printing +#' output is switched off. +#' @param .show_error A logical to control if passing wrong input +#' (`repositories` and `organizations`) should end with an error or not. +#' @details If you do not define `orgs` and `repos`, `GitStats` will be set to +#' scan whole Git platform (such as enterprise version of GitHub or GitLab), +#' unless it is a public platform. In case of a public one (like GitHub) you +#' need to define `orgs` or `repos` as scanning through all organizations may +#' take large amount of time. +#' @return A `GitStats` object with added information on host. +#' @examples +#' \dontrun{ +#' my_gitstats <- create_gitstats() %>% +#' set_github_host( +#' orgs = c("r-world-devs", "openpharma", "pharmaverse") +#' ) +#' } +#' @export +set_github_host <- function(gitstats, + host = NULL, + token = NULL, + orgs = NULL, + repos = NULL, + verbose = is_verbose(gitstats), + .show_error = TRUE) { + gitstats$set_github_host( + host = host, + token = token, + orgs = orgs, + repos = repos, + verbose = verbose, + .show_error = .show_error + ) + + return(invisible(gitstats)) +} + +#' @title Set GitLab host +#' @name set_gitlab_host +#' @inheritParams set_github_host +#' @details If you do not define `orgs` and `repos`, `GitStats` will be set to +#' scan whole Git platform (such as enterprise version of GitHub or GitLab), +#' unless it is a public platform. In case of a public one (like GitHub) you +#' need to define `orgs` or `repos` as scanning through all organizations may +#' take large amount of time. +#' @return A `GitStats` object with added information on host. +#' @examples +#' \dontrun{ +#' my_gitstats <- create_gitstats() %>% +#' set_gitlab_host( +#' token = Sys.getenv("GITLAB_PAT_PUBLIC"), +#' orgs = "mbtests" +#' ) +#' } +#' @export +set_gitlab_host <- function(gitstats, + host = NULL, + token = NULL, + orgs = NULL, + repos = NULL, + verbose = is_verbose(gitstats), + .show_error = TRUE) { + gitstats$set_gitlab_host( + host = host, + token = token, + orgs = orgs, + repos = repos, + verbose = verbose, + .show_error = .show_error + ) + + return(invisible(gitstats)) +} diff --git a/inst/set_hosts.R b/inst/set_hosts.R new file mode 100644 index 0000000..02eabe8 --- /dev/null +++ b/inst/set_hosts.R @@ -0,0 +1,14 @@ +git_stats <- create_gitstats() |> + set_github_host( + orgs = c("r-world-devs"), + repos = c("openpharma/DataFakR"), + token = Sys.getenv("GITHUB_PAT"), + .show_error = FALSE + ) |> + set_gitlab_host( + orgs = c("mbtests", "makbest"), + token = Sys.getenv("GITLAB_PAT_PUBLIC"), + .show_error = FALSE + ) + +git_stats diff --git a/man/set_github_host.Rd b/man/set_github_host.Rd index 68ab860..6d10db9 100644 --- a/man/set_github_host.Rd +++ b/man/set_github_host.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/gitstats_functions.R +% Please edit documentation in R/set_host.R \name{set_github_host} \alias{set_github_host} \title{Set GitHub host} @@ -10,7 +10,8 @@ set_github_host( token = NULL, orgs = NULL, repos = NULL, - verbose = is_verbose(gitstats) + verbose = is_verbose(gitstats), + .show_error = TRUE ) } \arguments{ @@ -30,6 +31,9 @@ pass it, \code{orgs} parameter should stay \code{NULL}.} \item{verbose}{A logical, \code{TRUE} by default. If \code{FALSE} messages and printing output is switched off.} + +\item{.show_error}{A logical to control if passing wrong input +(\code{repositories} and \code{organizations}) should end with an error or not.} } \value{ A \code{GitStats} object with added information on host. diff --git a/man/set_gitlab_host.Rd b/man/set_gitlab_host.Rd index 065713a..c9df975 100644 --- a/man/set_gitlab_host.Rd +++ b/man/set_gitlab_host.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/gitstats_functions.R +% Please edit documentation in R/set_host.R \name{set_gitlab_host} \alias{set_gitlab_host} \title{Set GitLab host} @@ -10,7 +10,8 @@ set_gitlab_host( token = NULL, orgs = NULL, repos = NULL, - verbose = is_verbose(gitstats) + verbose = is_verbose(gitstats), + .show_error = TRUE ) } \arguments{ @@ -30,6 +31,9 @@ pass it, \code{orgs} parameter should stay \code{NULL}.} \item{verbose}{A logical, \code{TRUE} by default. If \code{FALSE} messages and printing output is switched off.} + +\item{.show_error}{A logical to control if passing wrong input +(\code{repositories} and \code{organizations}) should end with an error or not.} } \value{ A \code{GitStats} object with added information on host. diff --git a/tests/testthat/_snaps/set_host.md b/tests/testthat/_snaps/set_host.md index 0cbab87..9dc1205 100644 --- a/tests/testthat/_snaps/set_host.md +++ b/tests/testthat/_snaps/set_host.md @@ -127,3 +127,17 @@ ! Please type your organization name as you see it in web URL. i E.g. do not use spaces. Organization names as you see on the page may differ from their web 'address'. +# When wrong orgs and repos are passed they are excluded but host is created + + Code + test_gitstats <- create_gitstats() %>% set_github_host(orgs = c("openpharma", + "r_world_devs"), repos = c("r-world-devs/GitStats", "r-world-devs/GitMetrics"), + verbose = TRUE, .show_error = FALSE) + Message + i Using PAT from GITHUB_PAT envar. + i Checking organizations... + ! Organization you provided does not exist: https://api.github.com/orgs/r_world_devs + i Checking repositories... + ! Repository you provided does not exist: https://api.github.com/repos/r-world-devs/GitMetrics + v Set connection to GitHub. + diff --git a/tests/testthat/test-02-get_commits-GitStats.R b/tests/testthat/test-02-get_commits-GitStats.R index 1a69732..6347484 100644 --- a/tests/testthat/test-02-get_commits-GitStats.R +++ b/tests/testthat/test-02-get_commits-GitStats.R @@ -45,7 +45,7 @@ test_that("get_commits works properly", { test_that("get_commits() works", { mockery::stub( get_commits, - "gitstats_object$get_commits", + "gitstats$get_commits", test_mocker$use("commits_table") ) commits_data <- get_commits( @@ -64,7 +64,7 @@ test_that("get_commits() works", { test_that("get_commits() returns error when since is not defined", { mockery::stub( get_commits, - "gitstats_object$get_commits", + "gitstats$get_commits", test_mocker$use("commits_table") ) expect_snapshot_error( diff --git a/tests/testthat/test-helpers.R b/tests/testthat/test-helpers.R index 827bcd4..2cb15eb 100644 --- a/tests/testthat/test-helpers.R +++ b/tests/testthat/test-helpers.R @@ -106,7 +106,9 @@ test_that("check_endpoint returns error if they are not correct", { expect_snapshot_error( check <- github_testhost_priv$check_endpoint( endpoint = "https://api.github.com/repos/r-worlddevs/GitStats", - type = "Repository" + type = "Repository", + verbose = TRUE, + .error = TRUE ) ) }) diff --git a/tests/testthat/test-set_host.R b/tests/testthat/test-set_host.R index c26f830..17b91c9 100644 --- a/tests/testthat/test-set_host.R +++ b/tests/testthat/test-set_host.R @@ -157,6 +157,19 @@ test_that("Error pops out when `org` does not exist", { ) }) +test_that("When wrong orgs and repos are passed they are excluded but host is created", { + skip_on_cran() + expect_snapshot( + test_gitstats <- create_gitstats() %>% + set_github_host( + orgs = c("openpharma", "r_world_devs"), + repos = c("r-world-devs/GitStats", "r-world-devs/GitMetrics"), + verbose = TRUE, + .show_error = FALSE + ) + ) +}) + test_that("Setting verbose for set_*_host() to FALSE works fine", { skip_on_cran() expect_no_error( diff --git a/vignettes/get_repos_with_code.Rmd b/vignettes/get_repos_with_code.Rmd index 03f298e..231345f 100644 --- a/vignettes/get_repos_with_code.Rmd +++ b/vignettes/get_repos_with_code.Rmd @@ -30,7 +30,7 @@ github_stats <- create_gitstats() %>% verbose_off() repos_urls <- get_repos_urls( - gitstats_object = github_stats, + gitstats = github_stats, with_code = "shiny" ) ```