Skip to content

Commit 3b1ca4e

Browse files
committed
Fix description_extract
1 parent bb6dd83 commit 3b1ca4e

30 files changed

+653
-161
lines changed

DESCRIPTION

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@ Suggests:
5252
githubinstall,
5353
UpSetR,
5454
grDevices,
55-
dlstats (>= 0.1.6)
55+
dlstats (>= 0.1.6),
56+
cranlogs,
57+
BiocPkgTools
58+
Remotes:
59+
github::neurogenomics/cranlogs
5660
RoxygenNote: 7.2.3
5761
VignetteBuilder: knitr
5862
License: GPL-3

NAMESPACE

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ export(github_pages_files)
1515
export(github_pages_vignettes)
1616
export(github_permissions)
1717
export(github_traffic)
18+
export(github_workflows)
1819
export(r_repos)
1920
export(r_repos_data)
2021
export(r_repos_downloads)
2122
export(r_repos_opts)
2223
export(readme_header)
24+
importFrom(RCurl,url.exists)
2325
importFrom(data.table,":=")
2426
importFrom(data.table,.SD)
2527
importFrom(data.table,as.data.table)
@@ -36,8 +38,10 @@ importFrom(methods,is)
3638
importFrom(parallel,mclapply)
3739
importFrom(stats,setNames)
3840
importFrom(stringr,str_split)
41+
importFrom(stringr,str_to_sentence)
3942
importFrom(testthat,is_testing)
4043
importFrom(utils,available.packages)
44+
importFrom(utils,capture.output)
4145
importFrom(utils,download.file)
4246
importFrom(utils,installed.packages)
4347
importFrom(utils,packageDescription)

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,16 @@
1414
- `r_repos_data`
1515
- `r_repos_downloads`
1616
- `r_repos_opts`
17+
* Added more robust func to get GH url: `get_github_url()`
1718

1819
## Bug fixes
1920

2021
* Elevate `rvest` to *Imports*.
2122
* Add `parallel` to *Imports*.
23+
* `r_repos_downloads_bioc` / `r_repos_downloads_cran`
24+
- Split queries into batches to prevent issues
25+
requesting with too many packages at once.
26+
- Parallelise.
2227

2328
# echogithub 0.99.0
2429

R/description_extract.R

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ description_extract <- function(desc_file = NULL,
2020
"repo",
2121
"authors"),
2222
add_html = FALSE,
23-
as_datatable = FALSE,
23+
as_datatable = FALSE,
2424
verbose = TRUE){
2525
#### Find or read DESCRIPTION file ####
2626
if(is.null(desc_file)){
@@ -29,52 +29,47 @@ description_extract <- function(desc_file = NULL,
2929
verbose = verbose)
3030
}
3131
force(desc_file)
32+
all_fields <- unique(c("owner","repo","authors","github_url",
33+
names(desc_file)))
3234
if(is.null(desc_file)) {
3335
stopper("desc_file is required for description_extract")
3436
}
3537
if(is.null(fields)) {
36-
fields <- c("owner","repo",names(desc_file))
37-
}
38+
fields <- all_fields
39+
}
3840
fields <- unique(fields)
39-
fields <- fields[fields %in% c("owner","repo",names(desc_file))]
41+
fields <- fields[fields %in% all_fields]
4042
#### Extract info ####
4143
messager("Extracting",length(fields),"field(s).",v=verbose)
4244
res <- lapply(stats::setNames(fields,
4345
fields),
4446
function(f){
4547
# messager("Inferring",f,"from DESCRIPTION file.",v=verbose)
4648
#### Check fields ####
47-
if(f=="owner") {
48-
i <- 2
49-
} else if(f=="repo") {
50-
i <- 1
51-
} else if(f %in% c("authors","Authors@R")) {
49+
if(f %in% c("authors","Authors@R","Author")) {
5250
authors <- description_authors(desc_file = desc_file,
5351
add_html = add_html)
5452
return(authors)
5553
} else if(f %in% names(desc_file)){
5654
return(desc_file[[f]])
57-
} else {
58-
stp <- paste("fields must be one of:",
59-
paste("\n -",c(
60-
eval(formals(description_extract)$fields),
61-
names(desc_file)
62-
), collapse = ""))
63-
stop(stp)
64-
}
65-
#### Parse info ####
66-
URL <- desc_file$URL
67-
if(is.na(URL)){
68-
stp <- "Cannot find URL field in DESCRIPTION file."
69-
stop(stp)
55+
} else if(f=="github_url"){
56+
gh_url <- get_github_url(desc_file = desc_file)
57+
return(gh_url)
58+
} else if(f=="owner"){
59+
gh_url <- get_github_url(desc_file = desc_file)
60+
if(is.null(gh_url)) {
61+
return(NULL)
62+
} else {
63+
return(rev(strsplit(gh_url,"/")[[1]])[2])
64+
}
65+
} else if(f=="repo"){
66+
gh_url <- get_github_url(desc_file = desc_file)
67+
if(is.null(gh_url)) {
68+
return(NULL)
69+
} else {
70+
return(rev(strsplit(gh_url,"/")[[1]])[1])
71+
}
7072
}
71-
i <- if(f=="owner") 2 else if(f=="repo") 1 else {
72-
stp <- "fields must be 'owner' or 'repo'"
73-
stop(stp)
74-
}
75-
info <- rev(strsplit(URL,"/")[[1]])[i]
76-
# messager(paste0("+ ",f,":"),info,v=verbose)
77-
return(info)
7873
})
7974
#### Return ####
8075
if(isTRUE(as_datatable)){

R/get_github_url.R

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
get_github_url <- function(desc_file){
2+
if(length(grep("github",desc_file$URL))>0){
3+
return(desc_file$URL)
4+
} else if (length(grep("github",desc_file$BugReports))>0){
5+
return(
6+
trimws(gsub("issues$","",desc_file$BugReports),
7+
whitespace = "/")
8+
)
9+
} else if (!is.null(desc_file$git_url)){
10+
return(
11+
paste("https://github.com",
12+
strsplit(desc_file$git_url,"[.]")[[1]][[2]],
13+
basename(desc_file$git_url),sep="/")
14+
)
15+
} else {
16+
return(NULL)
17+
}
18+
}

R/github_workflows.R

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#' GitHub workflows
2+
#'
3+
#' Get metadata on workflows that have been run via GitHub Actions.
4+
#' This includes the "conclusion" columns showing whether
5+
#' the workflow is currently passing.
6+
#' @param latest_only Only return the latest run of each workflow.
7+
#' @param workflows Select which workflows to return metadata for.
8+
#' @inheritParams github_files
9+
#' @returns \link[data.table]{data.table} containing workflow metadata.
10+
#'
11+
#' @export
12+
#' @importFrom gh gh gh_token
13+
#' @importFrom data.table .SD rbindlist setnames
14+
#' @examples
15+
#' dt <- github_workflows(owner="neurogenomics", repo="orthogene")
16+
github_workflows <- function(owner,
17+
repo,
18+
token = gh::gh_token(),
19+
latest_only = TRUE,
20+
workflows = NULL,
21+
verbose = TRUE){
22+
23+
conclusion <- name <- NULL;
24+
25+
messager("Searching for GitHub Actions in:",paste(owner,repo,sep="/"),
26+
v=verbose)
27+
##### Check inputs ####
28+
out <- check_owner_repo(owner = owner,
29+
repo = repo,
30+
verbose = verbose)
31+
owner <- out$owner
32+
repo <- out$repo
33+
#### Iterate over repos ####
34+
wdt <- lapply(seq_len(length(repo)), function(i){
35+
endpoint <- paste("https://api.github.com/repos",
36+
owner[i],repo[i],"actions/runs",sep="/")
37+
gh_response <- gh::gh(endpoint = endpoint,
38+
.token = token,
39+
per_page = 100)
40+
dt <- gh_to_dt(gh_response$workflow_runs)
41+
dt <- cbind(owner=owner[i], repo=repo[i], dt)
42+
#### Filter ####
43+
if(isTRUE(latest_only)){
44+
dt <- dt[conclusion!="cancelled",.SD[1], by="name"]
45+
}
46+
if(!is.null(workflows)){
47+
dt <- dt[name %in% workflows,]
48+
}
49+
return(dt)
50+
}) |> data.table::rbindlist(fill=TRUE)
51+
#### Check rows ####
52+
if(nrow(wdt)==0){
53+
messager("No matching workflows identified.",v=verbose)
54+
} else {
55+
data.table::setnames(wdt,"name","workflow")
56+
}
57+
return(wdt)
58+
}

R/is_url.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#' Borrowed from \code{seqminer} internal function}
77
#'
88
#' @keywords internal
9+
#' @importFrom RCurl url.exists
910
is_url <- function(path,
1011
protocols=c("http","https",
1112
"ftp","ftps",
@@ -15,8 +16,7 @@ is_url <- function(path,
1516
if(is.null(path)) return(FALSE)
1617
pattern <- paste(paste0("^",protocols,"://"),collapse = "|")
1718
if (grepl(pattern = pattern, x = path, ignore.case = TRUE)) {
18-
if(isTRUE(check_exists)){
19-
requireNamespace("RCurl")
19+
if(isTRUE(check_exists)){
2020
return(RCurl::url.exists(path))
2121
}
2222
return(TRUE)

R/r_repos.R

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,18 @@
33
#' Report on which repositories R packages are distributed through
44
#' (i.e. base R, CRAN, Bioc, rOpenSci, R-Forge, and/or GitHub).
55
#' @param which Which R repositories to extract data from.
6+
#' @param add_downloads Add the number of downloads from each repository.
7+
#' @param add_descriptions Add metadata from \emph{DESCRIPTION} files.
8+
#' @param add_github Add metadata from the respective GitHub repository
9+
#' for each R package (if any exists).
610
#' @param upset_plot Whether to create an upset plot
711
#' showing R package overlap between repositories.
812
#' @param show_plot Print the plot.
913
#' @param save_path Path to save upset plot to.
1014
#' @param verbose Print messages.
15+
#' @param height Saved plot height.
16+
#' @param width Saved plot width.
17+
#' @param nThread Number of threads to parallelise data queries across.
1118
#' @inheritParams BiocManager::repositories
1219
#' @returns Named list.
1320
#'
@@ -17,9 +24,15 @@
1724
#' report <- r_repos()
1825
r_repos <- function(which=r_repos_opts(),
1926
version=NULL,
27+
add_downloads=FALSE,
28+
add_descriptions=FALSE,
29+
add_github=FALSE,
2030
upset_plot=TRUE,
2131
show_plot=TRUE,
2232
save_path=tempfile(fileext = "upsetr.pdf"),
33+
height=7,
34+
width=10,
35+
nThread=1,
2336
verbose=TRUE){
2437

2538
if(isTRUE(upset_plot)) requireNamespace("UpSetR")
@@ -28,14 +41,20 @@ r_repos <- function(which=r_repos_opts(),
2841

2942
#### Gather data ####
3043
pkgs <- r_repos_data(which = which,
44+
add_downloads = add_downloads,
45+
add_descriptions = add_descriptions,
46+
add_github = add_github,
3147
version = version,
48+
nThread = nThread,
3249
verbose = verbose)
3350
#### Upset plot ####
3451
if(isTRUE(upset_plot)){
3552
upset <- r_repos_upset(pkgs = pkgs,
3653
save_path = save_path,
3754
show_plot = show_plot,
3855
verbose = verbose,
56+
height = height,
57+
width = width,
3958
sets.bar.color = "slategrey",
4059
main.bar.color = "slategrey",
4160
text.scale = 1.5,

0 commit comments

Comments
 (0)