Skip to content

Commit cb5aedf

Browse files
authored
Merge pull request #60 from ropensci-review-tools/network
network page for #59
2 parents a234d33 + d42aa50 commit cb5aedf

14 files changed

+126
-27
lines changed

DESCRIPTION

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: repometrics
22
Title: Metrics for Your Code Repository
3-
Version: 0.1.3.031
3+
Version: 0.1.3.042
44
Authors@R:
55
person("Mark", "Padgham", , "mark.padgham@email.com", role = c("aut", "cre"),
66
comment = c(ORCID = "0000-0003-2172-5265"))
@@ -25,6 +25,7 @@ Imports:
2525
Suggests:
2626
brio,
2727
httptest2,
28+
jsonlite,
2829
quarto,
2930
testthat (>= 3.0.0),
3031
tidyr,

NAMESPACE

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
export(repo_pkgstats_history)
44
export(repometrics_dashboard)
5-
export(repometrics_data_pkg)
5+
export(repometrics_data_repo)
66
export(repometrics_data_user)
77
importFrom(memoise,memoise)

R/analyse-users.R

+7-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
#' @noRd
1818
user_relation_matrices <- function (user_data) {
1919

20+
# Suppress no visible binding notes:
21+
followers <- following <- org_repo <- repo <- login <- num_comments <- NULL
22+
2023
user_names <- names (user_data)
2124
user_data <- add_user_login_cols (user_data) |>
2225
combine_user_data ()
@@ -100,7 +103,10 @@ combine_user_data <- function (user_data) {
100103

101104
user_relate_fields <- function (user_data, user_names, what = "commits") {
102105

103-
user_combs <- t (combn (user_names, m = 2L))
106+
# Suppress no visible binding notes:
107+
num_commits <- login <- repo <- n <- NULL
108+
109+
user_combs <- t (utils::combn (user_names, m = 2L))
104110
if (what == "commits") {
105111
user_data [[what]] <- dplyr::rename (user_data [[what]], n = num_commits)
106112
} else if (what == "commit_cmt") {

R/data-repo.R

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#' }
1111
#'
1212
#' @export
13-
repometrics_data_pkg <- function (path, step_days = 1L, num_cores = -1L) {
13+
repometrics_data_repo <- function (path, step_days = 1L, num_cores = -1L) {
1414

1515
cli::cli_alert_info ("Extracting package statistics ...")
1616
pkgstats <- repo_pkgstats_history (

R/quarto-dashboard.R

+39-8
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
1-
#' Start quarto dashboard with results of main \link{repometrics_data_pkg}
1+
#' Start quarto dashboard with results of main \link{repometrics_data_repo}
22
#' function.
33
#'
4-
#' @param data Results of main \link{repometrics_data_pkg} function applied to
5-
#' one package.
4+
#' @param data_repo Data on repository as returned from
5+
#' \link{repometrics_data_repo} function applied to one package.
6+
#' @param data_users Data on repository developers ("users" in GitHub terms), as
7+
#' returned from \link{repometrics_data_user} function applied to one package.
68
#' @param action One of "preview", to start and open a live preview of the
79
#' dashboard website, or "render" to render a static version without previewing
810
#' or opening.
911
#' @return (Invisibly) Path to main "index.html" document of quarto site. Note
1012
#' that the site must be served with `action = "preview"`, and will not work by
1113
#' simply opening this "index.html" file.
1214
#' @export
13-
repometrics_dashboard <- function (data, action = "preview") {
15+
repometrics_dashboard <- function (data_repo, data_users, action = "preview") {
1416

15-
check_dashboard_arg (data)
16-
data$pkgstats <- timestamps_to_dates (data$pkgstats)
17+
check_dashboard_arg (data_repo)
18+
data_repo$pkgstats <- timestamps_to_dates (data_repo$pkgstats)
1719

1820
requireNamespace ("brio")
21+
requireNamespace ("jsonlite")
1922
requireNamespace ("quarto")
2023
requireNamespace ("withr")
2124

@@ -25,16 +28,44 @@ repometrics_dashboard <- function (data, action = "preview") {
2528
path_src <- system.file ("extdata", "quarto", package = "repometrics")
2629
path_dest <- fs::path (fs::path_temp (), "quarto")
2730
dir <- fs::dir_copy (path_src, path_dest, overwrite = TRUE)
28-
saveRDS (data, fs::path (dir, "results-pkg.Rds"))
31+
saveRDS (data_repo, fs::path (dir, "results-repo.Rds"))
32+
saveRDS (data_users, fs::path (dir, "results-users.Rds"))
2933

30-
pkg_name <- data$pkgstats$desc_data$package [1]
34+
dat_user_network <- get_user_network (data_users)
35+
jsonlite::write_json (dat_user_network, fs::path (dir, "results-user-network.json"))
36+
37+
pkg_name <- data_repo$pkgstats$desc_data$package [1]
3138
quarto_insert_pkg_name (dir, pkg_name)
3239

3340
withr::with_dir (dir, {
3441
do.call (eval (parse (text = quarto_action)), list ())
3542
})
3643
}
3744

45+
get_user_network <- function (data_users) {
46+
47+
rels <- user_relation_matrices (data_users)
48+
index <- which (!grepl ("^login", names (rels)))
49+
relmat <- apply (as.matrix (rels [, index]), 2, function (i) i / sum (i))
50+
if (!is.matrix (relmat)) {
51+
relmat <- matrix (relmat, nrow = 1L)
52+
}
53+
relmat [which (is.na (relmat))] <- 0
54+
relvec <- 20 * rowSums (relmat) / ncol (relmat)
55+
reldf <- cbind (rels [, 1:2], value = relvec)
56+
names (reldf) <- c ("source", "target", "value")
57+
58+
netdat <- list (
59+
nodes = data.frame (
60+
id = unique (c (rels$login1, rels$login2)),
61+
group = 1L
62+
),
63+
links = reldf
64+
)
65+
66+
return (netdat)
67+
}
68+
3869
timestamps_to_dates <- function (data) {
3970

4071
lapply (data, function (i) {

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ The main data-gathering function requires just one parameter specifying the
4040
path to a local source repository:
4141

4242
``` r
43-
data <- repometrics_data_pkg (path)
43+
data <- repometrics_data_repo (path)
4444
```
4545

4646
The results can then be visualised as an interactive dashboard by running this

codemeta.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"codeRepository": "https://github.com/ropensci-review-tools/repometrics",
99
"issueTracker": "https://github.com/ropensci-review-tools/repometrics/issues",
1010
"license": "https://spdx.org/licenses/GPL-3.0",
11-
"version": "0.1.3.031",
11+
"version": "0.1.3.042",
1212
"programmingLanguage": {
1313
"@type": "ComputerLanguage",
1414
"name": "R",

inst/extdata/quarto/_quarto.yml

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ website:
99
left:
1010
- fn-stats.qmd
1111
- contributors.qmd
12+
- network.qmd
1213
right:
1314
- icon: "github"
1415
menu:

inst/extdata/quarto/contributors.qmd

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ requireNamespace ("tidyr", quietly = TRUE)
1717
## Git log
1818

1919
```{r load-data}
20-
dat <- readRDS ("results-pkg.Rds")
20+
dat <- readRDS ("results-repo.Rds")
2121
```
2222
```{r ctbs-git-data}
2323
ctbs <- dat$rm$contributors

inst/extdata/quarto/fn-stats.qmd

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ per function, along with the sum over all functions within the package. These
3131
the other measures.
3232

3333
```{r load-data}
34-
dat <- readRDS ("results-pkg.Rds")$pkgstats
34+
dat <- readRDS ("results-repo.Rds")$pkgstats
3535
```
3636
```{r stats-data}
3737
cols <- names (dat$stats) [which (!names (dat$stats) %in% c ("package", "version"))]

inst/extdata/quarto/network.qmd

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
title: "Network"
3+
execute:
4+
echo: false
5+
format:
6+
html:
7+
fig-width: 8
8+
fig-height: 4
9+
code-fold: false
10+
---
11+
12+
```{r load-pkg, echo = FALSE, message = FALSE}
13+
library (repometrics)
14+
requireNamespace ("dplyr", quietly = TRUE)
15+
requireNamespace ("tidyr", quietly = TRUE)
16+
```
17+
```{r load-data}
18+
dat_pkg <- readRDS ("results-repo.Rds")
19+
dat_users <- readRDS ("results-users.Rds")
20+
21+
deps <- dat_pkg$rm$dependencies
22+
get_dep_df <- function (deps, type = "Imports", group = 1L) {
23+
index <- which (deps$type == type)
24+
data.frame (id = deps$name [index], group = rep (group, length (index)))
25+
}
26+
27+
nodes_pkg_ <- rbind (
28+
get_dep_df (deps, "Imports", 1L),
29+
get_dep_df (deps, "Suggests", 2L)
30+
)
31+
nodes_user <- data.frame (id = dat_pkg$rm$contribs_from_gh_api$login, group = 4L)
32+
nodes_user$group [which (nodes_user$id %in% names (dat_users))] <- 3L
33+
```
34+
35+
```{ojs ForceGraph-import}
36+
import {ForceGraph} from "@d3/force-directed-graph-component"
37+
```
38+
39+
```{ojs import-network-data}
40+
network = FileAttachment("results-user-network.json").json()
41+
```
42+
43+
```{ojs ForceGraph-plot}
44+
chart = ForceGraph(network, {
45+
nodeId: d => d.id,
46+
nodeGroup: d => d.group,
47+
nodeTitle: d => `${d.id}\n${d.group}`,
48+
linkStrokeWidth: l => Math.sqrt(l.value),
49+
width,
50+
height: 600,
51+
invalidation // a promise to stop the simulation when the cell is re-run
52+
})
53+
```

man/repometrics_dashboard.Rd

+8-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/repometrics_data_pkg.Rd man/repometrics_data_repo.Rd

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-dashboard.R

+7-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ pkgstats <- repo_pkgstats_history (path, num_cores = 1L)
55
rm_data <- mock_rm_data ()
66
data0 <- list (pkgstats = pkgstats, rm = rm_data)
77

8+
user_data <- lapply (1:2, function (i) mock_user_rel_data ())
9+
names (user_data) <- c ("a", "b")
10+
811
test_that ("dashboard input errors", {
912

1013
data <- data0
@@ -34,11 +37,12 @@ test_that ("dashboard input errors", {
3437

3538
test_that ("dashboard build", {
3639

37-
data <- data0
38-
repometrics_dashboard (data, action = "render")
40+
data_repo <- data0
41+
data_users <- user_data
42+
repometrics_dashboard (data_repo, data_users, action = "render")
3943

4044
# Expect quarto docs to have been modified with package name:
41-
pkg_name <- data$pkgstats$desc_data$package [1]
45+
pkg_name <- data_repo$pkgstats$desc_data$package [1]
4246
path_tmp <- fs::path (fs::path_temp (), "quarto")
4347
expect_true (fs::dir_exists (path_tmp))
4448

0 commit comments

Comments
 (0)