Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorganize code for setting hosts, remove plot functions. #383

Merged
merged 15 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: GitStats
Title: Get Statistics from GitHub and GitLab
Version: 1.1.0.9004
Version: 1.1.0.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"),
Expand All @@ -13,16 +13,13 @@ Description: Obtain statistics in a standardized way from multiple Git services:
License: MIT + file LICENSE
Encoding: UTF-8
Roxygen: list(markdown = TRUE, r6 = TRUE)
RoxygenNote: 7.1.2
RoxygenNote: 7.3.1
Imports:
cli,
data.table,
dplyr,
ggplot2,
httr2,
lubridate,
magrittr,
plotly,
rlang (>= 1.1.0),
R6,
purrr (>= 1.0.0),
Expand Down
18 changes: 4 additions & 14 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ export(get_files)
export(get_release_logs)
export(get_repos)
export(get_users)
export(plot_commits_stats)
export(plot_repos)
export(reset)
export(reset_language)
export(set_host)
export(set_github_host)
export(set_gitlab_host)
export(set_params)
export(set_team_member)
export(show_data)
Expand All @@ -28,32 +27,23 @@ importFrom(cli,cli_alert_success)
importFrom(cli,cli_alert_warning)
importFrom(cli,col_green)
importFrom(cli,col_yellow)
importFrom(data.table,as.data.table)
importFrom(data.table,rbindlist)
importFrom(data.table,setorder)
importFrom(dplyr,distinct)
importFrom(dplyr,filter)
importFrom(dplyr,glimpse)
importFrom(dplyr,mutate)
importFrom(dplyr,relocate)
importFrom(ggplot2,aes)
importFrom(ggplot2,geom_line)
importFrom(ggplot2,geom_point)
importFrom(ggplot2,ggplot)
importFrom(httr2,req_headers)
importFrom(httr2,req_perform)
importFrom(httr2,request)
importFrom(httr2,resp_body_json)
importFrom(lubridate,floor_date)
importFrom(magrittr,"%>%")
importFrom(plotly,ggplotly)
importFrom(plotly,layout)
importFrom(purrr,keep)
importFrom(purrr,map)
importFrom(purrr,map_chr)
importFrom(rlang,"%||%")
importFrom(rlang,expr)
importFrom(stringr,str_length)
importFrom(stringr,str_remove_all)
importFrom(stringr,str_replace)
importFrom(utils,head)
importFrom(utils,URLdecode)
importFrom(utils,URLencode)
9 changes: 5 additions & 4 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

## Breaking changes:

- `set_host()` function is replaced with more explicit `set_github_host()` and `set_gitlab_host()`([#373](https://github.com/r-world-devs/GitStats/issues/373)). If you wish to connect to public host (e.g. `api.github.com`), you do not need to pass argument to `host` parameter.
- GitStats workflow is now simplified. To pull data on `repositories`, `commits`, `R_package_usage` you should use directly corresponding `get_*()` functions instead of `pull_*()` which are deprecated. These `get_*()` functions pull data from API, parse it into table, add some goodies (additional columns) if needed and return table instead of `GitStats` object, which in our opinion is more intuitive and user-friendly ([#345]((https://github.com/r-world-devs/GitStats/issues/345))). That means you do not need to run in pipe two or three additional function calls as before, e.g. `pull_repos(gitstats_object)` %>% `get_repos()` %>% get_repos_stats()`, but you just run
`get_repos(gitstats_object)` to get data you need.
- Moreover, if you run for the second time `get_*()` function without changing any parameters, GitStats will pull the data from its storage and not from API as for the first time, unless you change parameters for the function (e.g. starting date with `since` in `get_commits()`) or change settings for not using storage (`set_params(use_storage = FALSE)`).
- Moreover, if you run for the second time `get_*()` function `GitStats` will pull the data from its storage and not from API as for the first time, unless you change parameters for the function (e.g. starting date with `since` in `get_commits()`) or change settings for not using storage (`set_params(use_storage = FALSE)`).
- Along with that changes `get_repos_stats()` function was deprecated as its role was unclear - unlike `get_commit_stats()` it did not aggregate repositories data into new stats table, but added only some new numeric columns, like number of contributors (`contributors_n`) or last activity in `difftime` format, which is now done within `get_repos()` function.
- Meanwhile `get_commits_stats()` is preserved as it brings additional value with aggregating commits data into new statistical form.
- `pull_repos_contributors()` as a separate function is deprecated. The parameter `add_contributors` is now set by default to `TRUE` in `get_repos()` which seems more reasonable as user gets all the data.
- Plot functions are now `plot_repos()` (takes `repositories` table as an input) and `plot_commits_stats()` (takes `commits stats` as an input) - `gitstats_plot()` is deprecated.
- In `get_commits()` old parameters (`date_from` and `date_until`) were replaced with new more concise (`since` and `until`).
- Plot functions are no longer feature of `GitStats`, they have been deprecated as the package is meant to be basically for back end purposes and this is the field where developer's effort should now go ([#381](https://github.com/r-world-devs/GitStats/issues/381)). If needed and requested, plot functions may be brought up once more in next releases.
- In `get_commits()` old parameters (`date_from` and `date_until`) were replaced with new, more concise (`since` and `until`).
- A new parameter (`verbose`) in settings has been introduced for limiting messages to user when pulling data - you can turn it on/off with `verbose_on()`/`verbose_off()` functions.

## New features:
Expand All @@ -20,7 +21,7 @@

## Minor features:

- Commits response consists now of two new columns: `author_login` and `author_name` ([#332](https://github.com/r-world-devs/GitStats/issues/332)). This is due to the mix of github/gitlab handles and display names in the `author` column (the original author `name` field in commits API response).
- Commits response consists now of two new columns: `author_login` and `author_name` ([#332](https://github.com/r-world-devs/GitStats/issues/332)). This is due to the mix of GitHub/GitLab handles and display names in the `author` column (the original author `name` field in commits API response).
- Use stored repositories when pulling commits or files ([#159](https://github.com/r-world-devs/GitStats/issues/159)).
- Improve printing `GitStats` object - now when you return `GitStats` object in console, it prints `GitStats` data divided into sections to give more readable information to user: `scanning scope` (organizations, repositories and files), `search settings` (searched phrase, language, team name) and `storage` (the output tables stored in `GitStats` with basic information on dimensions) ([#329](https://github.com/r-world-devs/GitStats/issues/329)).

Expand Down
6 changes: 3 additions & 3 deletions R/EngineGraphQL.R
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,18 @@ EngineGraphQL <- R6::R6Class("EngineGraphQL",
date_from,
date_until = Sys.date(),
settings,
.storage = NULL) {
storage = NULL) {
if (!private$scan_all && settings$verbose) {
cli::cli_alert_info("[Engine:{cli::col_yellow('GraphQL')}][org:{org}] Pulling releases...")
}
if (is.null(repos)) {
if (is.null(.storage$repositories)) {
if (is.null(storage$repositories)) {
repos_table <- self$pull_repos(
org = org,
settings = settings
)
} else {
repos_table <- .storage$repositories %>%
repos_table <- storage$repositories %>%
dplyr::filter(
organization == org
)
Expand Down
37 changes: 6 additions & 31 deletions R/EngineGraphQLGitHub.R
Original file line number Diff line number Diff line change
Expand Up @@ -86,32 +86,23 @@ EngineGraphQLGitHub <- R6::R6Class("EngineGraphQLGitHub",
return(repos_table)
},

#' @description An empty method to satisfy engine iterator.
#' @param org An organization.
#' @param settings A list of `GitStats` settings.
#' @return Nothing.
pull_repos_supportive = function(org,
settings) {
NULL
},

#' @description Method to pull all commits from organization, optionally
#' filtered by team members.
#' @param org An organization.
#' @param repos A vector of repositories.
#' @param date_from A starting date to look commits for.
#' @param date_until An end date to look commits for.
#' @param settings A list of `GitStats` settings.
#' @param .storage A storage of `GitStats` object.
#' @param storage A storage of `GitStats` object.
#' @return A table of commits.
pull_commits = function(org,
repos = NULL,
date_from,
date_until,
settings,
.storage = NULL) {
storage = NULL) {
if (is.null(repos)) {
if (is.null(.storage$repositories)) {
if (is.null(storage$repositories)) {
repos_table <- self$pull_repos(
org = org,
settings = settings
Expand All @@ -120,7 +111,7 @@ EngineGraphQLGitHub <- R6::R6Class("EngineGraphQLGitHub",
if (settings$verbose) {
cli::cli_alert_info("Using repositories stored in `GitStats` object.")
}
repos_table <- .storage$repositories %>%
repos_table <- storage$repositories %>%
dplyr::filter(
organization == org
)
Expand Down Expand Up @@ -167,24 +158,8 @@ EngineGraphQLGitHub <- R6::R6Class("EngineGraphQLGitHub",
purrr::discard(~ length(.) == 0) %>%
private$prepare_commits_table(org)
return(commits_table)
},

#' @description Method to get commits.
#' @details This method must exist as it is called from the GitHost wrapper
#' above.
#' @param org An organization.
#' @param date_from A starting date to look commits for.
#' @param date_until An end date to look commits for.
#' @param settings A list of `GitStats` settings.
#' @return A table of commits.
pull_commits_supportive = function(org,
date_from,
date_until = Sys.date(),
settings) {
NULL
}

),
),
private = list(

# @description Iterator over pulling pages of repositories.
Expand Down Expand Up @@ -442,7 +417,7 @@ EngineGraphQLGitHub <- R6::R6Class("EngineGraphQLGitHub",
commits_row
}) %>%
purrr::discard(~ length(.) == 1) %>%
data.table::rbindlist(use.names = TRUE)
purrr::list_rbind()

if (nrow(commits_table) > 0) {
commits_table <- commits_table %>%
Expand Down
32 changes: 2 additions & 30 deletions R/EngineGraphQLGitLab.R
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ EngineGraphQLGitLab <- R6::R6Class("EngineGraphQLGitLab",
#' @return A table.
pull_repos = function(org,
settings) {
org <- gsub("%2f", "/", org)
org <- URLdecode(org)
if (settings$search_param == "org") {
if (!private$scan_all) {
if (settings$verbose) {
Expand All @@ -73,34 +73,6 @@ EngineGraphQLGitLab <- R6::R6Class("EngineGraphQLGitLab",
repos_table <- NULL
}
return(repos_table)
},

#' @description An empty method to satisfy engine iterator.
#' @param org An organization.
#' @param settings A list of `GitStats` settings.
#' @return Nothing.
pull_repos_supportive = function(org,
settings) {
NULL
},

#' @description Method to get commits.
#' @details This method is empty as this class does not support pulling
#' commits - it is done for GitLab via REST. Still the method must
#' exist as it is called from the GitHost wrapper above.
#' @param org An organization.
#' @param date_from A starting date to look commits for.
#' @param date_until An end date to look commits for.
#' @param settings A list of `GitStats` settings.
#' @param .storage A storage of `GitStats` object.
#' @return A table of commits.
pull_commits = function(org,
repos = NULL,
date_from,
date_until = Sys.date(),
settings,
.storage = NULL) {
NULL
}

),
Expand Down Expand Up @@ -237,7 +209,7 @@ EngineGraphQLGitLab <- R6::R6Class("EngineGraphQLGitLab",
# argument to iterate over it when pulling files.
# @return A response in a list form.
pull_file_from_org = function(org, file_path, pulled_repos = NULL) {
org <- gsub("%2f", "/", org)
org <- URLdecode(org)
if (!is.null(pulled_repos)) {
repos_table <- pulled_repos %>%
dplyr::filter(organization == org)
Expand Down
86 changes: 3 additions & 83 deletions R/EngineRest.R
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ EngineRest <- R6::R6Class("EngineRest",
initialize = function(rest_api_url = NA,
token = NA,
scan_all = FALSE) {
private$token <- token
self$rest_api_url <- rest_api_url
private$token <- private$check_token(token)
private$scan_all <- scan_all
},

Expand All @@ -36,46 +36,9 @@ EngineRest <- R6::R6Class("EngineRest",
} else {
result <- list()
}

return(result)
},

#' @description Check if repositories exist
#' @param repos A character vector of repositories
#' @return repos or NULL.
check_repositories = function(repos) {
repos <- purrr::map(repos, function(repo) {
private$check_endpoint(
repo = repo
)
return(repo)
}) %>%
purrr::keep(~ length(.) > 0) %>%
unlist()

if (length(repos) == 0) {
return(NULL)
}
repos
},

#' @description Check if organizations exist
#' @param orgs A character vector of organizations
#' @return orgs or NULL.
check_organizations = function(orgs) {
orgs <- purrr::map(orgs, function(org) {
org <- private$check_endpoint(
org = org
)
return(org)
}) %>%
purrr::keep(~ length(.) > 0) %>%
unlist()
if (length(orgs) == 0) {
return(NULL)
}
orgs
}

),
private = list(

Expand All @@ -85,49 +48,6 @@ EngineRest <- R6::R6Class("EngineRest",
# @field A boolean.
scan_all = FALSE,

# @description Check whether the token exists.
# @param token A token.
# @return A token.
check_token = function(token) {
if (nchar(token) == 0) {
cli::cli_abort(c(
"i" = "No token provided."
))
}
},

# @description Check whether the endpoint exists.
# @param repo Repository path.
# @param org Organization path.
check_endpoint = function(repo = NULL, org = NULL) {
if (!is.null(repo)) {
type <- "Repository"
repo_endpoint <- if(grepl("github", self$rest_api_url)) "/repos/" else "/projects/"
endpoint <- paste0(self$rest_api_url, repo_endpoint, repo)
object <- repo
}
if (!is.null(org)) {
type <- "Organization"
org_endpoint <- if(grepl("github", self$rest_api_url)) "/orgs/" else "/groups/"
endpoint <- paste0(self$rest_api_url, org_endpoint, org)
object <- org
}
withCallingHandlers(
{
self$response(endpoint = endpoint)
},
message = function(m) {
if (grepl("404", m)) {
cli::cli_alert_danger("{type} you provided does not exist or its name was passed in a wrong way: {endpoint}")
cli::cli_alert_warning("Please type your {tolower(type)} name as you see it in `url`.")
cli::cli_alert_info("E.g. do not use spaces. {type} names as you see on the page may differ from their 'address' name.")
object <<- NULL
}
}
)
return(object)
},

# Paginate contributors and parse response into character vector
pull_contributors_from_repo = function(contributors_endpoint, user_name) {
contributors_response <- private$paginate_results(contributors_endpoint)
Expand Down Expand Up @@ -166,7 +86,7 @@ EngineRest <- R6::R6Class("EngineRest",
})
data.frame(repo)
}) %>%
data.table::rbindlist()
purrr::list_rbind()

if (length(repos_dt) > 0) {
repos_dt <- dplyr::mutate(repos_dt,
Expand Down
Loading
Loading