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

326 new search package usage function #327

Merged
merged 10 commits into from
Dec 8, 2023
2 changes: 1 addition & 1 deletion 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.0.1.9000
Version: 1.0.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 Down
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ S3method(gitstats_plot,commits_stats)
S3method(gitstats_plot,repos_stats)
export("%>%")
export(create_gitstats)
export(get_R_package_usage)
export(get_commits)
export(get_commits_stats)
export(get_files)
Expand All @@ -12,6 +13,7 @@ export(get_repos)
export(get_repos_stats)
export(get_users)
export(gitstats_plot)
export(pull_R_package_usage)
export(pull_commits)
export(pull_files)
export(pull_repos)
Expand Down
7 changes: 6 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
# GitStats 1.0.1.9000
# GitStats 1.0.0.9005

## Features:

- added `pull_R_package_usage()` function to pull repositories where package name is found in DESCRIPTION or NAMESPACE files or code blobs with phrases related to using an R package (`library(package)`, `package::`) ([#326](https://github.com/r-world-devs/GitStats/issues/326)),
- added `pull_files()` with `get_files()` to pull content of text files ([#200](https://github.com/r-world-devs/GitStats/issues/200)),
- added a `default_branch` column to repositories output as a consequence of [#200](https://github.com/r-world-devs/GitStats/issues/200).

## Fixes:

- fixed pulling responses when GitLab groups have private or empty content ([#314](https://github.com/r-world-devs/GitStats/issues/314).

## Minor changes:

- rename column names for repository output - `id` to `repo_id` and `name` to `repo_name`.

# GitStats 1.0.0

## Breaking changes:
Expand Down
30 changes: 23 additions & 7 deletions R/EngineGraphQL.R
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ EngineGraphQL <- R6::R6Class("EngineGraphQL",
#' @param vars A list of named variables.
#' @return A list.
gql_response = function(gql_query, vars = "null") {
httr2::request(paste0(self$gql_api_url, "?")) %>%
httr2::req_headers("Authorization" = paste0("Bearer ", private$token)) %>%
httr2::req_body_json(list(query = gql_query, variables = vars)) %>%
httr2::req_perform() %>%
httr2::resp_body_json()
response <- private$perform_request(
gql_query = gql_query,
vars = vars
)
response_list <- httr2::resp_body_json(response)
return(response_list)
},

#' @description Get information on users in the form of table
Expand All @@ -51,14 +52,17 @@ EngineGraphQL <- R6::R6Class("EngineGraphQL",
#' an organization in a table format.
#' @param org An organization.
#' @param file_path A file path.
#' @param pulled_repos Optional parameter to pass repository output object.
#' @param settings A list of `GitStats` settings.
#' @return A table.
pull_files = function(org, file_path) {
pull_files = function(org, file_path, pulled_repos = NULL) {
if (!private$scan_all) {
cli::cli_alert_info("[Engine:{cli::col_yellow('GraphQL')}][org:{org}] Pulling {file_path} files...")
}
files_table <- private$pull_file_from_org(
org = org,
file_path = file_path
file_path = file_path,
pulled_repos = pulled_repos
) %>%
private$prepare_files_table(
org = org,
Expand All @@ -75,6 +79,18 @@ EngineGraphQL <- R6::R6Class("EngineGraphQL",
# @field A boolean.
scan_all = FALSE,

perform_request = function(gql_query, vars) {
response <- httr2::request(paste0(self$gql_api_url, "?")) %>%
httr2::req_headers("Authorization" = paste0("Bearer ", private$token)) %>%
httr2::req_body_json(list(query = gql_query, variables = vars)) %>%
httr2::req_retry(
is_transient = ~ httr2::resp_status(.x) == "400|502",
max_seconds = 60
) %>%
httr2::req_perform()
return(response)
},

# @description A method to pull information on user.
# @param username A login.
# @return A user response.
Expand Down
98 changes: 59 additions & 39 deletions R/EngineGraphQLGitHub.R
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ EngineGraphQLGitHub <- R6::R6Class("EngineGraphQLGitHub",
#' @param settings A list of `GitStats` settings.
#' @return A table.
pull_repos = function(org,
settings) {
settings) {
if (settings$search_param %in% c("org", "team")) {
if (settings$search_param == "org") {
if (!private$scan_all) {
Expand Down Expand Up @@ -89,7 +89,7 @@ EngineGraphQLGitHub <- R6::R6Class("EngineGraphQLGitHub",
#' @param settings A list of `GitStats` settings.
#' @return Nothing.
pull_repos_supportive = function(org,
settings) {
settings) {
NULL
},

Expand All @@ -101,14 +101,14 @@ EngineGraphQLGitHub <- R6::R6Class("EngineGraphQLGitHub",
#' @param settings A list of `GitStats` settings.
#' @return A table of commits.
pull_commits = function(org,
date_from,
date_until,
settings) {
date_from,
date_until,
settings) {
repos_table <- self$pull_repos(
org = org,
settings = list(search_param = "org")
)
repos_names <- repos_table$name
repos_names <- repos_table$repo_name

if (settings$search_param == "org") {
if (!private$scan_all) {
Expand Down Expand Up @@ -252,7 +252,11 @@ EngineGraphQLGitHub <- R6::R6Class("EngineGraphQLGitHub",
prepare_repos_table = function(repos_list) {
if (length(repos_list) > 0) {
repos_table <- purrr::map_dfr(repos_list, function(repo) {
repo$default_branch <- repo$default_branch$name
repo$default_branch <- if(!is.null(repo$default_branch)) {
repo$default_branch$name
} else {
""
}
repo$languages <- purrr::map_chr(repo$languages$nodes, ~ .$name) %>%
paste0(collapse = ", ")
repo$created_at <- gts_to_posixt(repo$created_at)
Expand All @@ -263,7 +267,7 @@ EngineGraphQLGitHub <- R6::R6Class("EngineGraphQLGitHub",
repo <- data.frame(repo) %>%
dplyr::relocate(
default_branch,
.after = name
.after = repo_name
)
})
} else {
Expand Down Expand Up @@ -458,31 +462,43 @@ EngineGraphQLGitHub <- R6::R6Class("EngineGraphQLGitHub",
return(user_table)
},

# @description Pull all given files from all repositories of an organization.
# @description Pull all given files from all repositories of an
# organization.
# @param org An organization.
# @param file_path Path to a file.
# @param pulled_repos Optional, if not empty, function will make use of the
# argument to iterate over it when pulling files.
# @return A response in a list form.
pull_file_from_org = function(org, file_path) {
repos_list <- private$pull_repos_from_org(
from = "org",
org = org
)
repositories <- purrr::map(repos_list, ~ .$name)
def_branches <- purrr::map(repos_list, ~ .$default_branch$name)
files_list <- purrr::map2(repositories, def_branches, function(repository, def_branch) {
files_query <- self$gql_query$files_by_repo()
files_response <- self$gql_response(
gql_query = files_query,
vars = list(
"org" = org,
"repo" = repository,
"file_path" = paste0(def_branch, ":", file_path)
)
pull_file_from_org = function(org, file_path, pulled_repos = NULL) {
if (is.null(pulled_repos)) {
repos_list <- private$pull_repos_from_org(
from = "org",
org = org
)
}) %>%
purrr::map(~ .$data$repository)
names(files_list) <- repositories
files_list <- purrr::discard(files_list, ~ length(.$object) == 0)
repositories <- purrr::map(repos_list, ~ .$repo_name)
def_branches <- purrr::map(repos_list, ~ .$default_branch$name)
} else {
repositories <- pulled_repos$repo_name
def_branches <- pulled_repos$default_branch
}
files_list <- purrr::map(file_path, function(file_path) {
files_list <- purrr::map2(repositories, def_branches, function(repository, def_branch) {
files_query <- self$gql_query$files_by_repo()
files_response <- self$gql_response(
gql_query = files_query,
vars = list(
"org" = org,
"repo" = repository,
"file_path" = paste0(def_branch, ":", file_path)
)
)
}) %>%
purrr::map(~ .$data$repository)
names(files_list) <- repositories
files_list <- purrr::discard(files_list, ~ length(.$object) == 0)
return(files_list)
})
names(files_list) <- file_path
return(files_list)
},

Expand All @@ -492,16 +508,20 @@ EngineGraphQLGitHub <- R6::R6Class("EngineGraphQLGitHub",
# @return A table with information on files.
prepare_files_table = function(files_response, org, file_path) {
if (!is.null(files_response)) {
files_table <- purrr::imap(files_response, function(repository, name) {
data.frame(
"repository_name" = repository$name,
"repository_id" = repository$id,
"organization" = org,
"file_path" = file_path,
"file_content" = repository$object$text,
"file_size" = repository$object$byteSize,
"api_url" = self$gql_api_url
)
files_table <- purrr::map(file_path, function(file) {
purrr::imap(files_response[[file]], function(repository, name) {
data.frame(
"repo_name" = repository$name,
"repo_id" = repository$id,
"organization" = org,
"file_path" = file,
"file_content" = repository$object$text,
"file_size" = repository$object$byteSize,
"repo_url" = repository$url,
"api_url" = self$gql_api_url
)
}) %>%
purrr::list_rbind()
}) %>%
purrr::list_rbind()
} else {
Expand Down
Loading