Skip to content

Commit 4a19e54

Browse files
committed
add support for OSF repositories
also update rendering to handle the option for details see codecheckers/register#25
1 parent 74f8d62 commit 4a19e54

11 files changed

+241
-25
lines changed

DESCRIPTION

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: codecheck
22
Title: Helper Functions for CODECHECK Project
3-
Version: 0.0.0.9008
3+
Version: 0.0.0.9009
44
Authors@R:
55
c(person(given = "Stephen",
66
family = "Eglen",
@@ -15,7 +15,16 @@ Authors@R:
1515
Description: This contains helper functions for CODECHECKERS (<https://codecheck.org.uk>).
1616
License: MIT + file LICENSE
1717
Depends: R (>= 4.0.0), gh, R.cache, parsedate
18-
Imports: yaml, xtable, stringr, rmarkdown, knitr, jsonlite, assertthat, rorcid
18+
Imports:
19+
yaml,
20+
xtable,
21+
stringr,
22+
rmarkdown,
23+
knitr,
24+
jsonlite,
25+
assertthat,
26+
rorcid,
27+
osfr
1928
Encoding: UTF-8
2029
LazyData: true
2130
RoxygenNote: 7.1.1

NAMESPACE

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ importFrom(R.cache,addMemoization)
2121
importFrom(R.cache,getCacheRootPath)
2222
importFrom(gh,gh)
2323
importFrom(knitr,kable)
24+
importFrom(osfr,osf_download)
25+
importFrom(osfr,osf_ls_files)
26+
importFrom(osfr,osf_retrieve_node)
2427
importFrom(parsedate,parse_date)
2528
importFrom(rmarkdown,render)
2629
importFrom(rorcid,check_dois)

R/configuration.R

Lines changed: 90 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,118 @@
1+
#' Retrieve a codecheck.yml file from a remote repository
2+
#'
3+
#' @author Daniel Nüst
4+
#' @param x the repo specification
5+
get_codecheck_yml_uncached <- function(x) {
6+
spec <- parse_repository_spec(x)
7+
8+
result <- switch (spec[["type"]],
9+
"github" = get_codecheck_yml_github(spec[["repo"]]),
10+
"osf" = get_codecheck_yml_osf(spec[["repo"]])
11+
)
12+
13+
return(result)
14+
}
15+
16+
#' Retrieve a codecheck.yml file from a GitHub repository
17+
#'
118
#' @author Daniel Nüst
219
#' @importFrom gh gh
3-
get_codecheck_yml_uncached <- function(repo) {
4-
repo_files <- gh::gh("GET /repos/codecheckers/:repo/contents/",
5-
repo = repo,
20+
#' @param x the org/repo to download the file from
21+
get_codecheck_yml_github <- function(x) {
22+
org_repo <- strsplit(x, "/", fixed = TRUE)[[1]]
23+
24+
if (length(org_repo) != 2) {
25+
stop("Incomplete repo specification for type 'github', need 'org/repo' but have '", x, "'")
26+
}
27+
28+
repo_files <- gh::gh("GET /repos/:org/:repo/contents/",
29+
org = org_repo[[1]],
30+
repo = org_repo[[2]],
631
.accept = "application/vnd.github.VERSION.raw")
732
repo_file_names <- sapply(repo_files, "[[", "name")
833

934
if ("codecheck.yml" %in% repo_file_names) {
1035
config_file_response <- gh::gh(
11-
"GET /repos/codecheckers/:repo/contents/:file",
12-
repo = repo,
36+
"GET /repos/:org/:repo/contents/:file",
37+
org = org_repo[[1]],
38+
repo = org_repo[[2]],
1339
file = "codecheck.yml",
1440
.accept = "application/vnd.github.VERSION.raw")
1541
config_file <- yaml::read_yaml(text = config_file_response$message)
1642
return(config_file)
1743
} else {
44+
warning("codecheck.yml not found in list of repository files for ", x)
45+
return(NULL)
46+
}
47+
}
48+
49+
#' Retrieve a codecheck.yml file from an OSF project
50+
#'
51+
#' @author Daniel Nüst
52+
#' @param x the OSF id (5 characters)
53+
#' @importFrom osfr osf_retrieve_node osf_ls_files osf_download
54+
get_codecheck_yml_osf <- function(x) {
55+
repo <- osfr::osf_retrieve_node(x)
56+
repo_files <- osfr::osf_ls_files(repo, pattern = "codecheck.yml")
57+
58+
if (nrow(repo_files) == 1) {
59+
temp_dir <- tempdir()
60+
osfr::osf_download(repo_files, path = temp_dir)
61+
local_file <- file.path(temp_dir, "codecheck.yml")
62+
config_file <- yaml::read_yaml(file = local_file)
63+
file.remove(local_file)
64+
return(config_file)
65+
} else {
66+
warning("codecheck.yml not found in list of repository files for https://osf.io/", x)
1867
return(NULL)
1968
}
2069
}
2170

71+
#' Parse the repository specification in the column "Repo" in the register CSV file
72+
#'
73+
#' Based roughly on [`remotes::parse_one_extra`](https://github.com/r-lib/remotes/blob/master/R/deps.R#L519)
74+
#'
75+
#' Supported variants:
76+
#'
77+
#' - `osf::ABC12`
78+
#' - `github::codecheckers/Piccolo-2020`
79+
#'
80+
#' @author Daniel Nüst
81+
#' @param x the repository specification to parse
82+
#' @return a named character vector with the items `type` and `repo`
83+
parse_repository_spec <- function(x) {
84+
pieces <- strsplit(x, "::", fixed = TRUE)[[1]]
85+
86+
#if (length(pieces) == 1) {
87+
#type <- "github"
88+
#repo <- paste0("codecheckers/", pieces)
89+
#} else
90+
if (length(pieces) == 2) {
91+
type <- pieces[1]
92+
repo <- pieces[2]
93+
} else {
94+
stop("Malformed repository specification '", x, "'")
95+
}
96+
97+
if (! type %in% c("github", "osf")) {
98+
stop("Unsupported repository type '", type, "'")
99+
}
100+
101+
return(c(type = type, repo = repo))
102+
}
103+
22104
get_codecheck_yml_cached <- R.cache::addMemoization(get_codecheck_yml_uncached)
23105

24106
#' Get the CODECHECK configuration file from a repository
25107
#'
26-
#' @param repo Repository in the codecheckers organisation on GitHub
108+
#' @param x Repository in the codecheckers organisation on GitHub
27109
#'
28110
#' @author Daniel Nüst
29111
#' @importFrom R.cache addMemoization
30112
#'
31113
#' @export
32-
get_codecheck_yml <- function(repo) {
33-
configuration <- get_codecheck_yml_cached(repo)
114+
get_codecheck_yml <- function(x) {
115+
configuration <- get_codecheck_yml_cached(x)
34116
return(configuration)
35117
}
36118

R/register.R

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,23 @@ register_render <- function(register = read.csv("register.csv", as.is = TRUE),
6464

6565
# turn repositories into links for table rendering
6666
register_table$Repository <- sapply(X = register$Repository,
67-
FUN = function(repository_name) {
68-
if (!is.na(repository_name)) {
69-
urrl <- paste0("https://github.com/codecheckers/",
70-
repository_name)
71-
paste0("[", repository_name, "](", urrl, ")")
67+
FUN = function(repository) {
68+
spec <- parse_repository_spec(repository)
69+
70+
if (!is.na(spec)) {
71+
urrl <- "#"
72+
73+
if (spec[["type"]] == "github") {
74+
urrl <- paste0("https://github.com/", spec[["repo"]])
75+
paste0("[", spec[["repo"]], "](", urrl, ")")
76+
} else if (spec[["type"]] == "osf") {
77+
urrl <- paste0("https://osf.io/", spec[["repo"]])
78+
paste0("[", spec[["repo"]], "](", urrl, ")")
79+
} else {
80+
repository
81+
}
7282
} else {
73-
repository_name
83+
repository
7484
}
7585
})
7686

@@ -133,11 +143,14 @@ register_render <- function(register = read.csv("register.csv", as.is = TRUE),
133143
register_table$`Paper reference` <- stringr::str_trim(references)
134144
register_table$`Repository Link` <- sapply(
135145
X = register$Repository,
136-
FUN = function(repository_name) {
137-
if (!is.na(repository_name)) {
138-
paste0("https://github.com/codecheckers/", repository_name)
146+
FUN = function(repository) {
147+
spec <- parse_repository_spec(repository)
148+
if (spec[["type"]] == "github") {
149+
paste0("https://github.com/", spec[["repo"]])
150+
} else if (spec[["type"]] == "osf") {
151+
paste0("https://osf.io/", spec[["repo"]])
139152
} else {
140-
NA
153+
repository
141154
}
142155
}
143156
)
@@ -168,12 +181,16 @@ register_render <- function(register = read.csv("register.csv", as.is = TRUE),
168181
#' - Does the repo have a LICENSE?
169182
#'
170183
#' @param register A `data.frame` with all required information for the register's view
184+
#' @param from The first register entry to check
185+
#' @param to The last register entry to check
171186
#'
172187
#' @author Daniel Nüst
173188
#' @importFrom gh gh
174189
#' @export
175-
register_check <- function(register = read.csv("register.csv", as.is = TRUE)) {
176-
for (i in seq_len(nrow(register))) {
190+
register_check <- function(register = read.csv("register.csv", as.is = TRUE),
191+
from = 1,
192+
to = nrow(register)) {
193+
for (i in seq(from = from, to = to)) {
177194
cat("Checking", toString(register[i, ]), "\n")
178195
entry <- register[i, ]
179196

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
tinytest::using(ttdo)
2+
3+
# Invalid or unsupported ----
4+
expect_error(get_codecheck_yml("unsupported::repo/spec"),
5+
pattern = "Unsupported repository type 'unsupported")
6+
expect_error(get_codecheck_yml("github::not_org_and_repo"),
7+
pattern = "Incomplete repo specification for type 'github'(.*)'not_org_and_repo'")
8+
9+
expect_warning(get_codecheck_yml("github::codecheckers/register"),
10+
pattern = "codecheck.yml not found in(.*)codecheckers/register")
11+
expect_warning(get_codecheck_yml("osf::6K5FH"),
12+
pattern = "codecheck.yml not found in(.*)https://osf.io/6K5FH")
13+
14+
# GitHub ----
15+
expect_silent({ piccolo <- get_codecheck_yml("github::codecheckers/Piccolo-2020") })
16+
expect_equal(piccolo$report, "http://doi.org/10.5281/zenodo.3674056")
17+
18+
# OSF ----
19+
expect_silent({ agile <- get_codecheck_yml("osf::5SVMT") })
20+
expect_equal(agile$report, "https://doi.org/10.17605/OSF.IO/5SVMT")

man/get_codecheck_yml.Rd

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/get_codecheck_yml_github.Rd

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/get_codecheck_yml_osf.Rd

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/get_codecheck_yml_uncached.Rd

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/parse_repository_spec.Rd

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)