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

Last changes to release. #308

Merged
merged 17 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@
.Ruserdata
example_workflow_Roche.R
example_branch.R
docs
inst/doc
6 changes: 3 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Package: GitStats
Title: Get Statistics from Git Hosting Services
Version: 0.1.0.9011
Title: Get Statistics from GitHub and GitLab
Version: 1.0.0
Authors@R: c(
person(given = "Maciej", family = "Banaś", email = "[email protected]", role = c("aut", "cre")),
person(given = "Maciej", family = "Banas", email = "[email protected]", role = c("aut", "cre")),
person(given = "Kamil", family = "Koziej", email = "[email protected]", role = "aut"),
person(given = "Karolina", family = "Marcinkowska", email = "[email protected]", role = "aut"),
person(given = "Matt", family = "Secrest", email = "[email protected]", role = "aut")
Expand Down
1 change: 0 additions & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ importFrom(cli,cli_alert_success)
importFrom(cli,cli_alert_warning)
importFrom(cli,col_green)
importFrom(cli,col_yellow)
importFrom(data.table,":=")
importFrom(data.table,as.data.table)
importFrom(data.table,rbindlist)
importFrom(data.table,setorder)
Expand Down
65 changes: 41 additions & 24 deletions NEWS.md
marcinkowskak marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,27 +1,44 @@
GitStats (development version)

- added `get_*_stats` functions to prepare summary stats from pulled data: repositories and commits (I: #276),
- rename and refactor plot functions to one generic `gitstats_plot` which takes as an input `repos_stats` or `commits_stats` (I: #276),
- changed names of `get_*` to `pull_*` functions; `get_*` functions are now to retrieve already pulled data from GitStats object (I: #294),
- changed name of `setup` to `set_params` function (I: #294),
- set new name for `set_connection` function: `set_host` as it is more informative (and shorter) (I: #271),
- changed name of a function: `add_team_member` to `set_team_member` (I: #271),
- added setting tokens by default - if a user does have all the PATs set up in environment variables (as e.g. `GITHUB_PAT` or `GITLAB_PAT`), there is no need to pass them as an argument to `set_connection` (I: #120 PR: #268),
- added `pull_users()` function to pull information on users (I: #199 PR: #238),
- added possibility of scanning whole internal git platforms if no `orgs` are passed (I: #258),
- added switching to REST engine in case GraphQL fails with 502 error (I: #225 PRs: #227 (for repos) #261 (for commits))
- added `get_orgs()` function to print all organizations (I: #283),
- added GraphQL engine for getting GitLab repos by organization (I: #218 PR: #233)
- removed `contributors` as basic stat when pulling `repos` by `org` and by `phrase` to improve speed of pulling repositories data. Added `pull_repos_contributors()` user function and `add_contributors` parameter to `pull_repos()` function to add conditionally information on contributors to repositories table (I: #235 PRs: #243 #264)
- added resetting all settings to default with `reset()` function (I: #270)
- added resetting language in your search preferences with `reset_language()` or setting `language` parameter to `All` in `setup()` function (I: #231 PR: #265)
- OOP optimization: moved method on adding issues do repository table via REST to privates (I: #235 PR: #243)
- handled errors when tokens do not grant access (I: #242 PR: #247)
- in repositories output set `api_url` column as an address to the repo, not the host (I: #201 PR: #249)
- fixed adding GitLab subgroups (I: #176),
- exported pipe operator (`%>%`) (I: #289).

GitStats 0.1.0
# GitStats 1.0.0

## Breaking changes:

### New functions:

- added `get_*_stats()` functions to prepare summary stats from pulled data: repositories and commits ([#276](https://github.com/r-world-devs/GitStats/issues/276)),
- rename and refactor plot functions to one generic `gitstats_plot()` which takes as an input `repos_stats` or `commits_stats` class objects ([#276](https://github.com/r-world-devs/GitStats/issues/276)),

### New names for core functions:

- changed names from `get_*` to `pull_*`; `get_*` functions are now to retrieve already pulled data from GitStats object ([#294](https://github.com/r-world-devs/GitStats/issues/294)),
- changed name from `setup()` to `set_params()` ([#294](https://github.com/r-world-devs/GitStats/issues/294)),
- changed name from `set_connection()` to `set_host()` ([#271](https://github.com/r-world-devs/GitStats/issues/271)),
- changed name from `add_team_member()` to `set_team_member()` ([#271](https://github.com/r-world-devs/GitStats/issues/271)).

## Major changes:

### New features:

- added setting tokens by default - if the user does have all the PATs set up in environment variables (as e.g. `GITHUB_PAT` or `GITLAB_PAT`), there is no need to pass them as an argument to `set_host()` ([#120](https://github.com/r-world-devs/GitStats/issues/120)),
- added `pull_users()` function to pull information on users ([#199](https://github.com/r-world-devs/GitStats/issues/199)),
- added possibility of scanning whole internal git platforms if no `orgs` are passed ([#258](https://github.com/r-world-devs/GitStats/issues/258)),
- added `get_orgs()` function to print all organizations ([#283](https://github.com/r-world-devs/GitStats/issues/283)),
- added resetting all settings to default with `reset()` function ([#270](https://github.com/r-world-devs/GitStats/issues/270))
- added resetting language in your search preferences with `reset_language()` or setting `language` parameter to `All` in `setup()` function ([#231](https://github.com/r-world-devs/GitStats/issues/231))

### Improving performance with REST and GraphQL APIs:

- added switching to REST engine in case GraphQL fails with 502 error ([#225](https://github.com/r-world-devs/GitStats/issues/225))
- added GraphQL engine for getting GitLab repositories by organization ([#218](https://github.com/r-world-devs/GitStats/issues/218))
- removed `contributors` as basic stat when pulling `repos` by `org` and by `phrase` to improve speed of pulling repositories data. Added `pull_repos_contributors()` user function and `add_contributors` parameter to `pull_repos()` function to add conditionally information on contributors to repositories table ([#235](https://github.com/r-world-devs/GitStats/issues/235))

## Minor changes:

- handled errors with proper messages when tokens do not grant access ([#242](https://github.com/r-world-devs/GitStats/issues/242) [#301](https://github.com/r-world-devs/GitStats/issues/301)),
- in repositories output set `api_url` column as an address to the repository, not the host ([#201](https://github.com/r-world-devs/GitStats/issues/201)),
- fixed adding GitLab subgroups ([#176](https://github.com/r-world-devs/GitStats/issues/176)),
- exported pipe operator (`%>%`) ([#289](https://github.com/r-world-devs/GitStats/issues/289)).

# GitStats 0.1.0

This is the first release of GitStats with given features:

Expand Down
6 changes: 6 additions & 0 deletions R/EngineGraphQL.R
marcinkowskak marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#' @noRd
#' @importFrom dplyr distinct mutate relocate filter
#'
#' @title A EngineGraphQL class
Expand Down Expand Up @@ -62,6 +63,11 @@ EngineGraphQL <- R6::R6Class("EngineGraphQL",
gql_query = self$gql_query$user(),
vars = list("user" = username)
)
if (length(response$errors) > 0) {
cli::cli_abort(
response$errors[[1]]$message
)
}
return(response)
}
)
Expand Down
6 changes: 6 additions & 0 deletions R/EngineGraphQLGitHub.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#' @noRd
#' @importFrom dplyr distinct mutate filter
#'
#' @title A EngineGraphQLGitHub class
Expand Down Expand Up @@ -30,6 +31,11 @@ EngineGraphQLGitHub <- R6::R6Class("EngineGraphQLGitHub",
end_cursor = end_cursor
)
)
if (length(response$errors) > 0) {
cli::cli_abort(
response$errors[[1]]$message
)
}
orgs_list <- purrr::map(response$data$search$edges, ~stringr::str_match(.$node$url, "[^\\/]*$"))
full_orgs_list <- append(full_orgs_list, orgs_list)
has_next_page <- response$data$search$pageInfo$hasNextPage
Expand Down
13 changes: 13 additions & 0 deletions R/EngineGraphQLGitLab.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#' @noRd
#' @importFrom dplyr relocate
#'
#' @title A EngineGraphQLGitLab class
Expand Down Expand Up @@ -29,6 +30,15 @@ EngineGraphQLGitLab <- R6::R6Class("EngineGraphQLGitLab",
gql_query = self$gql_query$groups(),
vars = list("groupCursor" = group_cursor)
)
if (length(response$data$groups$edges) == 0) {
cli::cli_abort(
c(
"x" = "Empty response.",
"!" = "Your token probably does not cover scope to pull organizations.",
"i" = "Set `read_api` scope when creating GitLab token."
)
)
}
orgs_list <- purrr::map(response$data$groups$edges, ~.$node$fullPath)
full_orgs_list <- append(full_orgs_list, orgs_list)
has_next_page <- response$data$groups$pageInfo$hasNextPage
Expand Down Expand Up @@ -107,6 +117,9 @@ EngineGraphQLGitLab <- R6::R6Class("EngineGraphQLGitLab",
users = users,
repo_cursor = repo_cursor
)
if (length(repos_response$data$group) == 0) {
cli::cli_abort("Empty")
}
if (from == "org") {
core_response <- repos_response$data$group$projects
repos_list <- core_response$edges
Expand Down
1 change: 1 addition & 0 deletions R/EngineRest.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#' @noRd
#' @importFrom httr2 request req_headers req_perform resp_body_json
#' @importFrom cli cli_abort col_green
#' @importFrom rlang %||%
Expand Down
1 change: 1 addition & 0 deletions R/EngineRestGitHub.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#' @noRd
#' @title A EngineRestGitHub class
#' @description A class for methods wrapping GitHub's REST API responses.
EngineRestGitHub <- R6::R6Class("EngineRestGitHub",
Expand Down
1 change: 1 addition & 0 deletions R/EngineRestGitLab.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#' @noRd
#' @title A EngineRestGitLab class
#' @description A class for methods wrapping GitLab's REST API responses.
EngineRestGitLab <- R6::R6Class("EngineRestGitLab",
Expand Down
1 change: 1 addition & 0 deletions R/GQLQueryGitHub.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#' @noRd
#' @title A GQLQueryGitHub class
#' @description A class with methods to build GraphQL Queries for GitHub.

Expand Down
1 change: 1 addition & 0 deletions R/GQLQueryGitLab.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#' @noRd
#' @title A GQLQueryGitLab class
#' @description A class with methods to build GraphQL Queries for GitLab.

Expand Down
80 changes: 47 additions & 33 deletions R/GitHost.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#' @noRd
#' @importFrom R6 R6Class
#' @importFrom rlang expr
#' @importFrom cli cli_alert_danger cli_alert_success
Expand All @@ -8,12 +9,12 @@
GitHost <- R6::R6Class("GitHost",
public = list(

#' @description Create a new `GitHost` object
#' @description Create a new `GitHost` object.
#' @param orgs A character vector of organisations (owners of repositories
#' in case of GitHub and groups of projects in case of GitLab).
#' @param token A token.
#' @param api_url An API url.
#' @return A new `GitHost` object
#' @param api_url An API URL.
#' @return A new `GitHost` object.
initialize = function(orgs = NA,
token = NA,
api_url = NA) {
Expand Down Expand Up @@ -80,27 +81,29 @@ GitHost <- R6::R6Class("GitHost",
#' @param repos_table A table of repositories.
#' @return A table of repositories with added information on contributors.
pull_repos_contributors = function(repos_table) {
repos_table <- repos_table %>%
dplyr::filter(grepl(gsub("/v+.*", "", private$api_url), api_url))
repos_table <- purrr::map_dfr(private$engines, function (engine) {
if (inherits(engine, "EngineRest")) {
engine$pull_repos_contributors(
repos_table
)
} else {
NULL
}
})
if (!is.null(repos_table) && nrow(repos_table) > 0) {
repos_table <- repos_table %>%
dplyr::filter(grepl(gsub("/v+.*", "", private$api_url), api_url))
repos_table <- purrr::map_dfr(private$engines, function (engine) {
if (inherits(engine, "EngineRest")) {
engine$pull_repos_contributors(
repos_table
)
} else {
NULL
}
})
}
},

#' @description A method to get information on commits.
#' @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 data.frame of commits
#' @return A data.frame of commits.
pull_commits = function(date_from,
date_until = Sys.Date(),
settings) {
date_until = Sys.Date(),
settings) {
if (settings$search_param == "phrase") {
cli::cli_abort(c(
"x" = "Pulling commits by phrase in code blobs is not supported.",
Expand Down Expand Up @@ -149,9 +152,9 @@ GitHost <- R6::R6Class("GitHost",
return(commits_table)
},

#' @description Get information about users
#' @param users A character vector of users
#' @return Table of users
#' @description Pull information about users.
#' @param users A character vector of users.
#' @return Table of users.
pull_users = function(users) {
users_table <- purrr::map(private$engines, function(engine) {
if (inherits(engine, "EngineGraphQL")) {
Expand All @@ -166,7 +169,7 @@ GitHost <- R6::R6Class("GitHost",
),
private = list(

# @field A REST API url.
# @field A REST API URL.
api_url = NULL,

# @field A token.
Expand Down Expand Up @@ -315,28 +318,39 @@ GitHost <- R6::R6Class("GitHost",
},
error = function(e) {
if (!private$scan_all) {
if (grepl("502", e)) {
cli::cli_alert_warning(cli::col_yellow("HTTP 502 Bad Gateway Error. Switch to another Engine."))
} else {
cli::cli_alert_warning(cli::col_yellow("Error. Switch to another Engine."))
if (grepl("502|400", e)) {
if (grepl("502", e)) {
cli::cli_alert_warning(cli::col_yellow("HTTP 502 Bad Gateway Error."))
} else if (grepl("400", e)) {
cli::cli_alert_warning(cli::col_yellow("HTTP 400 Bad Request."))
}
cli::cli_alert_info("Switching to REST engine.")
repos_list <<- purrr::map(private$engines, function (engine) {
engine$pull_repos_supportive(
org = org,
settings = settings
)
})
} else if (grepl("Empty", e)) {
cli::cli_abort(
c(
"x" = "Empty response.",
"!" = "Your token probably does not cover scope to pull repositories.",
"i" = "Set `read_api` scope when creating GitLab token."
)
)
}
}
repos_list <<- purrr::map(private$engines, function (engine) {
engine$pull_repos_supportive(
org = org,
settings = settings
)
})
})
repos_table_org <- purrr::list_rbind(repos_list)
return(repos_table_org)
}, .progress = private$scan_all) %>%
purrr::list_rbind()
},

# add do repos table `api_url` column
# @description Add `api_url` column to repos table.
add_repo_api_url = function(repos_table){
if (length(repos_table) > 0) {
if (!is.null(repos_table) && nrow(repos_table) > 0) {
repos_table <- if (private$host == "GitHub") {
dplyr::mutate(
repos_table,
Expand Down
Loading