library(flexdashboard) library(gh) library(jsonlite) library(lubridate) library(forcats) library(dplyr) library(purrr) library(tibble) library(codetools) # there was a weird error on connect that needed this library(DT) library(tidyversedashboard) library(tidyr) library(sparkline) library(ggplot2) on_macos <- function() tolower(Sys.info()[["sysname"]]) == "darwin" gh_colors <- list( green = "#2cbe4e", red = "#CB2434", purple = "#6f42c1") start <- params$start duration <- format(today() - start, format = "%d") orgs <- scan(text = params$orgs, what = "character", sep = ",", strip.white = TRUE, quiet = TRUE) privacy <- normalize_privacy(params$privacy) # plus1 emoji p1 <- "\U0001f44d"
options(repos = c(CRAN='https://cloud.r-project.org')) pr_data <- tryCatch( map_dfr(orgs, org_pr, privacy = privacy), error = function(e) message(e$content$errors)) if (!is.null(pr_data)) { prs <- pr_data %>% filter(updated >= start) %>% mutate(reviewer = map2(reviews, comments, function(reviews, comments) unique(c(reviews$reviewer, comments$commenter)))) %>% select(owner, repo, issue, author, created, updated, reviewer) %>% unnest(cols = c(reviewer)) %>% filter(reviewer != author, reviewer != "codecov.io") %>% mutate( reviewer = github_user_home(reviewer), author = github_user_home(author)) pr_authors <- prs %>% group_by(author) %>% select(-reviewer) %>% unique() %>% tally(sort = TRUE) pr_reviewers <- prs %>% group_by(reviewer) %>% select(-author) %>% unique() %>% tally(sort = TRUE) pr_pairs <- prs %>% group_by(author, reviewer) %>% tally(sort = TRUE) } else { pr_authors <- NULL pr_reviewers <- NULL pr_pairs <- NULL }
repo_data <- map(orgs, org_data, privacy) repo_summary <- map_dfr(repo_data, "summary") issues <- map_dfr(repo_data, "issues")
r duration
issue progressissue_data <- map_dfr(orgs, issue_progress, start, privacy) issue_data2 <- issue_data %>% mutate( type = factor(levels = c("issue", "pull_request"), case_when( type == "Issue" ~ "issue", type == "PullRequest" ~ "pull_request")), status = factor(levels = c("opened", "closed", "merged"), case_when( merged >= start ~ "merged", closed >= start ~ "closed", opened >= start ~ "opened", TRUE ~ NA_character_)), event = case_when( status == "merged" ~ merged, status == "closed" ~ closed, status == "opened" ~ opened) )
totals <- issue_data2 %>% group_by(type, status) %>% tally() %>% mutate(n = if_else(status == "closed" | status == "merged", n * -1L, n)) %>% na.omit()
valueBox(totals %>% filter(status == "opened") %>% pull("n") %>% sum(), icon = "fa-exclamation-circle", color = "success")
valueBox(totals %>% filter(type == "issue", status == "closed") %>% pull("n") %>% abs(), icon = "fa-times-circle", color = "danger")
valueBox(totals %>% filter(type == "pull_request" & (status == "merged" | status == "closed")) %>% pull("n") %>% sum() %>% abs(), icon = "ion-merge", color = "info")
r duration
changechange <- sum(totals$n) valueBox(change, icon = "fa-exclamation-circle", color = if (change > 0) "success" else "danger")
valueBox(nrow(issues), icon = "fa-exclamation-circle")
r duration
progressissue_progress_table <- issue_data2 %>% # Add maintiner to the table left_join(mutate(repo_summary, maintainer = desc_maintainer(description)) %>% select(repo, maintainer), by = c("package" = "repo")) %>% group_by(type, status) %>% arrange(event) %>% select(owner, package, issue, maintainer, event, status, type) %>% na.omit() data_table(issue_progress_table)
Issues with status modified (
r start
-r now()
).
issue_data3 <- issue_data2 %>% filter(!is.na(event)) %>% select(event, owner, package, num = issue, type, status) %>% mutate( date = as.Date(event), event = NULL, n = if_else(status %in% c("closed", "merged"), -1, 1) ) daily <- issue_data3 %>% group_by(date, type, status, ) %>% summarise(n = sum(n)) daily %>% mutate(status = fct_relevel(status, "opened", "merged")) %>% ggplot(aes(date, n, fill = type)) + geom_col() + facet_grid(status ~ ., scales = "free_y", space = "free") + labs( title = "Daily changes in issues and PRs", x = NULL, y = NULL ) + scale_y_continuous(breaks = scales::breaks_width(20), expand = c(0, 5)) + scale_fill_brewer(palette = "Set1", guide = NULL) + scale_x_date(date_breaks = "1 week", date_labels = "%b %d", date_minor_breaks = "1 day")
r start
-r now()
summary_table <- repo_summary %>% rename("package" = "repo") %>% mutate( weekly_downloads = num_downloads(.$package, "last-week"), maintainer = desc_maintainer(description), reverse_deps = reverse_dependencies(package), dev_deps = desc_dev_deps(description), github_status = github_status_badge(owner, package), cran_status = cran_status_badge(package), activity = map2(owner, package, weekly_commits)) %>% select(owner, package, maintainer, watchers, reverse_deps, weekly_downloads, open_issues, prs, p1, everything(), -description) %>% rename(!!p1 := p1)
# A custom datatable with a sparkline column dt <- sparkline_table( summary_table, sparkline_column = which(colnames(summary_table) == "activity"), colnames = c("52 week commit activity" = "activity")) dt
substitute_emoji <- function(x) { m <- gregexpr(":[^[:space:]]+:", x) regmatches(x, m) <- lapply(regmatches(x, m), function(xx) map_chr(gsub(":", "", xx), purrr::possibly(emo::ji, ""))) x } # linkify the titles, and replace emoji issue_table <- mutate(issues, title = glue::glue('<a rel="noopener" target="_blank" href="https://github.com/{owner}/{repo}/issues/{issue}">{title}</a>'), labels = substitute_emoji(map_chr(labels, paste, collapse = ", "))) %>% rename(!!p1 := p1) data_table(issue_table)
r duration
pull request summarydata_table(pr_authors)
data_table(pr_reviewers)
data_table(pr_pairs)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.