Skip to content

Commit 8829f04

Browse files
authored
Merge pull request #32 from ropensci-review-tools/cm-data
cm data
2 parents c9e7dbf + a3ad8dd commit 8829f04

17 files changed

+169
-78
lines changed

DESCRIPTION

+1-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.1.069
3+
Version: 0.1.1.077
44
Authors@R:
55
person("Mark", "Padgham", , "mark.padgham@email.com", role = c("aut", "cre"),
66
comment = c(ORCID = "0000-0003-2172-5265"))

R/chaoss-internal-change-req.R

+13-4
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,18 @@
1515
chaoss_internal_change_req <- function (path, end_date = Sys.Date ()) {
1616

1717
log <- git_log_in_period (path, end_date, get_repometrics_period ())
18-
res <- NA_integer_
19-
if (nrow (log) > 0L) {
20-
res <- length (which (log$merge)) / nrow (log)
21-
}
18+
prs <- cm_data_prs_from_gh_api (path)
19+
prs <- prs [which (prs$merged), ]
20+
closed_dates <- as.Date (prs$closed_at)
21+
start_date <- end_date - get_repometrics_period ()
22+
index <- which (closed_dates >= start_date & closed_dates <= end_date)
23+
prs <- prs [index, ]
24+
25+
num_commits <- vapply (prs$commit_oids, function (i) {
26+
length (strsplit (i, ",") [[1]])
27+
}, integer (1L), USE.NAMES = FALSE)
28+
29+
res <- sum (num_commits) / nrow (log)
30+
2231
return (res)
2332
}

R/chaoss-internal-num-ctb.R

+4-15
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,7 @@ chaoss_internal_num_contributors <- function (path, end_date = Sys.Date ()) {
22

33
log <- git_log_in_period (path, end_date, get_repometrics_period ())
44

5-
auths_un <- unique (log$author)
6-
7-
# separate handles from emails:
8-
emails <- regmatches (auths_un, gregexpr ("<.*>", auths_un))
9-
emails <- vapply (emails, function (i) {
10-
ifelse (length (i) == 0L, "", gsub ("<|>", "", i))
11-
}, character (1L))
12-
handles <- gsub ("<.*$", "", auths_un)
13-
14-
# Remove any duplicates of either, but excluding non-entries:
5+
# Remove any duplicates of either names or emails, but excluding non-entries:
156
rm_dup_rows <- function (x) {
167
x <- gsub ("\\s+", "", x)
178
index <- seq_along (x)
@@ -21,15 +12,13 @@ chaoss_internal_num_contributors <- function (path, end_date = Sys.Date ()) {
2112
}
2213
return (index)
2314
}
24-
index1 <- rm_dup_rows (handles)
25-
index2 <- rm_dup_rows (emails)
15+
index1 <- rm_dup_rows (log$aut_name)
16+
index2 <- rm_dup_rows (log$aut_email)
2617

2718
# Then extract only instances where neither handles nor emails are
2819
# duplicated:
2920
index_table <- table (c (index1, index2))
3021
index <- as.integer (names (index_table) [which (index_table == 2L)])
3122

32-
auths_un <- auths_un [index]
33-
34-
return (length (auths_un))
23+
return (length (index))
3524
}

R/chaoss-internal.R

-28
This file was deleted.

R/cm-data-dependencies.R

+4-2
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,19 @@ cm_data_dependencies <- function (path) {
2727
cm_data_libyears <- function (path) {
2828

2929
deps <- cm_data_dependencies (path)
30-
cran_db <- data.frame (tools::CRAN_package_db ())
30+
cran_db <- data.frame (cran_pkg_db ())
3131
index <- match (deps$name, cran_db$Package)
3232
deps$cran_version <- cran_db$Version [index]
3333
deps$published <- as.Date (cran_db$Published [index])
3434
deps <- deps [which (!is.na (deps$published)), ]
3535

36-
rel <- releases_from_gh_api (path, latest_only = TRUE)
36+
rel <- cm_data_releases_from_gh_api (path, latest_only = TRUE)
3737
rel_date <- as.Date (strftime (rel$published_at, format = "%Y-%m-%d"))
3838

3939
dt <- difftime (deps$published, rel_date, units = "days")
4040
dt <- as.numeric (dt) / 365.25 # In years
4141

4242
c (mean = mean (dt), median = stats::median (dt))
4343
}
44+
45+
cran_pkg_db <- memoise::memoise (tools::CRAN_package_db)

R/cm-data-gh-contribs.R

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
contribs_from_log <- function (log) {
1+
cm_data_contribs_from_log <- function (path) {
2+
3+
log <- cm_data_gitlog (path)
24

35
gh_handle <- unique (log$aut_name)
46
gh_email <- log$aut_email [match (gh_handle, log$aut_name)]
@@ -27,7 +29,7 @@ contribs_from_log <- function (log) {
2729
) [index, ]
2830
}
2931

30-
contribs_from_gh_api <- function (path, n_per_page = 100) {
32+
cm_data_contribs_from_gh_api_internal <- function (path, n_per_page = 100) {
3133

3234
is_test_env <- Sys.getenv ("REPOMETRICS_TESTS") == "true"
3335

@@ -80,6 +82,8 @@ contribs_from_gh_api <- function (path, n_per_page = 100) {
8082

8183
return (ctbs)
8284
}
85+
cm_data_contribs_from_gh_api <-
86+
memoise::memoise (cm_data_contribs_from_gh_api_internal)
8387

8488
user_from_gh_api <- function (user) {
8589

R/cm-data-gh-issues.R

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
issues_from_gh_api <- function (path, n_per_page = 100) {
1+
cm_data_issues_from_gh_api_internal <- function (path, n_per_page = 100) {
22

33
is_test_env <- Sys.getenv ("REPOMETRICS_TESTS") == "true"
44

@@ -69,6 +69,8 @@ issues_from_gh_api <- function (path, n_per_page = 100) {
6969

7070
return (issues)
7171
}
72+
cm_data_issues_from_gh_api <-
73+
memoise::memoise (cm_data_issues_from_gh_api_internal)
7274

7375
get_issue_reactions <- function (body) {
7476

@@ -87,7 +89,7 @@ get_issue_reactions <- function (body) {
8789
return (reaction_counts)
8890
}
8991

90-
issue_comments_from_gh_api <- function (path, n_per_page = 100) {
92+
cm_data_issue_comments_from_gh_api_internal <- function (path, n_per_page = 100) {
9193

9294
is_test_env <- Sys.getenv ("REPOMETRICS_TESTS") == "true"
9395

@@ -138,3 +140,5 @@ issue_comments_from_gh_api <- function (path, n_per_page = 100) {
138140
issue_body = issue_body
139141
)
140142
}
143+
cm_data_issue_comments_from_gh_api <-
144+
memoise::memoise (cm_data_issue_comments_from_gh_api_internal)

R/cm-data-gh-prs.R

+3-2
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ gh_prs_qry <- function (org = "ropensci-review-tools",
107107
return (q)
108108
}
109109

110-
prs_from_gh_api <- function (path, n_per_page = 30L) {
110+
cm_data_prs_from_gh_api_internal <- function (path, n_per_page = 30L) {
111111

112112
is_test_env <- Sys.getenv ("REPOMETRICS_TESTS") == "true"
113113
if (is_test_env) {
@@ -158,7 +158,7 @@ prs_from_gh_api <- function (path, n_per_page = 30L) {
158158
reviews <- lapply (pr_data, function (i) {
159159
login <- vapply (i$reviews$nodes, function (j) j$author$login, character (1L))
160160
state <- vapply (i$reviews$nodes, function (j) j$state, character (1L))
161-
submitted_at <- vapply (i$reviews$nodes, function (j) j$submittedAt, character (1L))
161+
submitted_at <- vapply (i$reviews$nodes, function (j) null2na_char (j$submittedAt), character (1L))
162162
body <- vapply (i$reviews$nodes, function (j) j$body, character (1L))
163163
data.frame (
164164
login = login,
@@ -193,3 +193,4 @@ prs_from_gh_api <- function (path, n_per_page = 30L) {
193193
reviews = I (reviews)
194194
)
195195
}
196+
cm_data_prs_from_gh_api <- memoise::memoise (cm_data_prs_from_gh_api_internal)

R/cm-data-gh-releases.R

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
releases_from_gh_api <- function (path, n_per_page = 100L, latest_only = FALSE) {
1+
cm_data_releases_from_gh_api_internal <- function (path, n_per_page = 100L, latest_only = FALSE) {
22

33
checkmate::assert_integerish (n_per_page)
44
checkmate::assert_logical (latest_only)
@@ -48,3 +48,4 @@ releases_from_gh_api <- function (path, n_per_page = 100L, latest_only = FALSE)
4848
published_at = vapply (body, function (i) i$published_at, character (1L))
4949
)
5050
}
51+
cm_data_releases_from_gh_api <- memoise::memoise (cm_data_releases_from_gh_api_internal)

R/cm-data-gh-repo.R

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
repo_from_gh_api <- function (path) {
1+
cm_data_repo_from_gh_api_internal <- function (path) {
22

33
or <- org_repo_from_path (path)
44

@@ -36,3 +36,4 @@ repo_from_gh_api <- function (path) {
3636
default_branch = null2na_char (body$default_branch)
3737
)
3838
}
39+
cm_data_repo_from_gh_api <- memoise::memoise (cm_data_repo_from_gh_api_internal)

R/cm-data-git.R

+23
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,26 @@ cm_data_gitlog_internal <- function (path) {
5050
)
5151
}
5252
cm_data_gitlog <- memoise::memoise (cm_data_gitlog_internal)
53+
54+
git_log_in_period <- function (path, end_date = Sys.Date (), period = 90) {
55+
56+
checkmate::assert_character (path, len = 1L)
57+
checkmate::assert_directory (path)
58+
checkmate::assert_date (end_date)
59+
60+
log <- cm_data_gitlog (path)
61+
62+
if (nrow (log) == 0) {
63+
return (log)
64+
}
65+
dates <- as.Date (log$time)
66+
today_minus_period <- as.Date (end_date - period)
67+
index <- which (dates >= today_minus_period)
68+
log <- log [index, ]
69+
70+
if (dates [1] > end_date) {
71+
log <- log [which (dates <= end_date), ]
72+
}
73+
74+
return (log)
75+
}

R/cm-data.R

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
cm_data <- function (path) {
2+
3+
data_fns <- get_cm_data_fns ()
4+
5+
if (all_cm_data_fns_memoised (data_fns, path)) {
6+
res <- lapply (data_fns, function (i) {
7+
do.call (i, list (path))
8+
})
9+
} else {
10+
res <- pbapply::pblapply (data_fns, function (i) {
11+
do.call (i, list (path))
12+
})
13+
}
14+
names (res) <- gsub ("^cm\\_data\\_", "", data_fns)
15+
16+
return (res)
17+
}
18+
19+
get_cm_data_fns <- function () {
20+
21+
pkg_fns <- ls (envir = asNamespace ("repometrics"))
22+
data_fns <- grep ("^cm\\_data\\_", pkg_fns, value = TRUE)
23+
data_fns [which (!grepl ("\\_internal$", data_fns))]
24+
}
25+
26+
all_cm_data_fns_memoised <- function (data_fns, path) {
27+
is_memoised <- vapply (data_fns, function (i) {
28+
tryCatch (
29+
memoise::has_cache (get (i)) (path),
30+
error = function (e) FALSE
31+
)
32+
}, logical (1L))
33+
34+
length (which (is_memoised)) > (length (data_fns) / 2)
35+
}

R/cm-metrics-num-commits.R

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
cm_metrics_num_commits <- function (path, end_date = Sys.Date ()) {
2+
3+
log <- git_log_in_period (path, end_date, get_repometrics_period ())
4+
5+
return (nrow (log))
6+
}

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.1.069",
11+
"version": "0.1.1.077",
1212
"programmingLanguage": {
1313
"@type": "ComputerLanguage",
1414
"name": "R",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
[
2+
{
3+
"url": "ghrepos/repo//releases/158953460",
4+
"assets_url": "ghrepos/repo//releases/158953460/assets",
5+
"upload_url": "https://uploads.github.com/repos/repo//releases/158953460/assets{?name,label}",
6+
"html_url": "https://github.com/repo//releases/tag/v1.0.5",
7+
"id": 158953460,
8+
"author": {
9+
"login": "mpadge",
10+
"id": 6697851,
11+
"node_id": "MDQ6VXNlcjY2OTc4NTE=",
12+
"avatar_url": "https://avatars.githubusercontent.com/u/6697851?v=4",
13+
"gravatar_id": "",
14+
"url": "ghusers/mpadge",
15+
"html_url": "https://github.com/mpadge",
16+
"followers_url": "ghusers/mpadge/followers",
17+
"following_url": "ghusers/mpadge/following{/other_user}",
18+
"gists_url": "ghusers/mpadge/gists{/gist_id}",
19+
"starred_url": "ghusers/mpadge/starred{/owner}{/repo}",
20+
"subscriptions_url": "ghusers/mpadge/subscriptions",
21+
"organizations_url": "ghusers/mpadge/orgs",
22+
"repos_url": "ghusers/mpadge/repos",
23+
"events_url": "ghusers/mpadge/events{/privacy}",
24+
"received_events_url": "ghusers/mpadge/received_events",
25+
"type": "User",
26+
"user_view_type": "public",
27+
"site_admin": false
28+
},
29+
"node_id": "RE_kwDOAwboEs4JeW_0",
30+
"tag_name": "v1.0.5",
31+
"target_commitish": "main",
32+
"name": "goodpractice 1.0.5",
33+
"draft": false,
34+
"prerelease": false,
35+
"created_at": "2024-06-05T09:31:17Z",
36+
"published_at": "2024-06-05T09:34:42Z",
37+
"assets": [
38+
39+
],
40+
"tarball_url": "ghrepos/repo//tarball/v1.0.5",
41+
"zipball_url": "ghrepos/repo//zipball/v1.0.5",
42+
"body": "* New maintainer: rOpenSci\r\n* Package reinstated on CRAN, after archiving of previous version.\r\n* CRAN fixes - skipping failing test and adding \\alias{goodpractice} to package Rd\r\n* Adding docs.ropensci site to DESCRIPTION",
43+
"reactions": {
44+
"url": "ghrepos/repo//releases/158953460/reactions",
45+
"total_count": 1,
46+
"+1": 0,
47+
"-1": 0,
48+
"laugh": 0,
49+
"hooray": 0,
50+
"confused": 0,
51+
"heart": 1,
52+
"rocket": 0,
53+
"eyes": 0
54+
}
55+
}
56+
]

tests/testthat/test-chaoss-metrics-internal.R

+1-13
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ test_that ("chaoss internal num_commits", {
44

55
path <- generate_test_pkg ()
66

7-
n <- chaoss_internal_num_commits (path, end_date = end_date)
7+
n <- cm_metrics_num_commits (path, end_date = end_date)
88
expect_equal (n, 4L)
99

1010
n <- chaoss_internal_num_contributors (path, end_date = end_date)
@@ -39,15 +39,3 @@ test_that ("chaoss has CI internal", {
3939

4040
fs::dir_delete (path)
4141
})
42-
43-
test_that ("chaoss internal change requests", {
44-
45-
path <- generate_test_pkg ()
46-
47-
x <- chaoss_internal_change_req (path, end_date = end_date)
48-
expect_equal (x, 0)
49-
x <- chaoss_internal_change_req (path, end_date = Sys.Date ())
50-
expect_equal (x, NA_integer_) # no commits, so NA returned
51-
52-
fs::dir_delete (path)
53-
})

0 commit comments

Comments
 (0)