Skip to content

feat: add support for ROR IDs #159

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ Authors@R: c(
person("Jim", "Hester", , "[email protected]", role = "aut"),
person("Maëlle", "Salmon", role = "ctb",
comment = c(ORCID = "0000-0002-2815-0399")),
person("Posit Software, PBC", role = c("cph", "fnd"))
person("Posit Software, PBC", role = c("cph", "fnd"),
comment = c(ROR = "03wc8by49"))
)
Maintainer: Gábor Csárdi <[email protected]>
Description: Tools to read, write, create, and manipulate DESCRIPTION
Expand Down Expand Up @@ -35,7 +36,7 @@ Config/testthat/edition: 3
Encoding: UTF-8
Language: en-US
Roxygen: list(r6 = FALSE, load = "installed", markdown = TRUE)
RoxygenNote: 7.3.2
RoxygenNote: 7.3.2.9000
Collate:
'assertions.R'
'authors-at-r.R'
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export(desc_add_me)
export(desc_add_orcid)
export(desc_add_remotes)
export(desc_add_role)
export(desc_add_ror)
export(desc_add_to_collate)
export(desc_add_urls)
export(desc_bump_version)
Expand Down
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# desc (development version)

* New `add_ror()` method and `desc_add_ror()` functions make it possible to add ROR IDs to authors directly instead of via the `comment` argument. (@maelle, #158)

* All functions and methods managing possibly non individual authors (`add_author()`, `del_author()`, `add_role()`, `del_role()`, `search_for_author()`, etc.) gain a `ror` argument. (@maelle, #158)

* `desc_get_built()` no longer fails if Built spans multiple lines
(#145, @seankross).

Expand Down
95 changes: 80 additions & 15 deletions R/authors-at-r.R
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,16 @@

search_for_author <- function(authors, given = NULL, family = NULL,
email = NULL, role = NULL, comment = NULL,
orcid = NULL) {
orcid = NULL, ror = NULL) {

matching <-
ngrepl(given, authors$given) &
ngrepl(family, authors$family) &
ngrepl(email, authors$email) &
ngrepl(role, authors$role) &
ngrepl(comment, authors$comment) &
ngrepl(orcid, authors$comment)
ngrepl(orcid, authors$comment) &
ngrepl(ror, authors$comment)

list(index = which(matching), authors = authors[matching])
}
Expand Down Expand Up @@ -160,28 +161,40 @@

check_author_args <- function(given = NULL, family = NULL, email = NULL,
role = NULL, comment = NULL,
orcid = NULL) {
orcid = NULL, ror = NULL) {

# orcid is for individuals, ror for organizations
# so cannot have both
stopifnot(
is.null(orcid) || is.null(ror)
)

stopifnot(
is_string_or_null(given),
is_string_or_null(family),
is_string_or_null(email),
is_character_or_null(role),
is_named_character_or_null(comment),
is_string_or_null(orcid)
is_string_or_null(orcid),
is_string_or_null(ror)
)
}

#' @importFrom utils person

idesc_add_author <- function(self, private, given, family, email, role,
comment, orcid = NULL) {
check_author_args(given, family, email, role, comment, orcid)
comment, orcid = NULL, ror = NULL) {
check_author_args(given, family, email, role, comment, orcid, ror)
orig <- idesc_get_authors(self, private, ensure = FALSE)

if (!is.null(orcid)) {
comment["ORCID"] <- orcid
}

if (!is.null(ror)) {
comment["ROR"] <- ror

Check warning on line 195 in R/authors-at-r.R

View check run for this annotation

Codecov / codecov/patch

R/authors-at-r.R#L195

Added line #L195 was not covered by tests
}

newp <- person(given = given, family = family, email = email,
role = role, comment = comment)
new_authors <- if (is.null(orig)) newp else c(orig, newp)
Expand All @@ -190,16 +203,17 @@


idesc_add_role <- function(self, private, role, given, family, email,
comment, orcid = NULL) {
comment, orcid = NULL, ror = NULL) {

stopifnot(is.character(role))
check_author_args(given, family, email, comment = comment,
orcid = orcid)
orcid = orcid, ror = ror)

orig <- idesc_get_authors(self, private, ensure = FALSE)
wh <- search_for_author(
orig, given = given, family = family, email = email, comment = comment,
orcid = orcid,
ror = ror,
role = NULL
)

Expand Down Expand Up @@ -236,6 +250,13 @@
call. = FALSE)
}

other_orcid <- search_for_author(orig, orcid = orcid)
if (length(other_orcid$index) > 0) {
stop("Already an author with this ORCID ID.
ORCID IDs have to be distinct.",
call. = FALSE)
}

orig <- set_author_field(
orig,
wh$index,
Expand All @@ -247,15 +268,52 @@
self$set_authors(orig)
}

idesc_add_ror <- function(self, private, ror, given, family, email,
comment, role) {
check_author_args(given = given, family = family,
email = email,
comment = comment,
ror = ror, role = role)
orig <- idesc_get_authors(self, private, ensure = FALSE)
wh <- search_for_author(
orig, given = given, family = family, email = email, comment = comment,
ror = NULL,
role = role
)
if (length(wh$index) > 1) {
stop("More than one author correspond to the provided arguments.
ROR IDs have to be distinct.",
call. = FALSE)
}

other_ror <- search_for_author(orig, ror = ror)
if (length(other_ror$index) > 0) {
stop("Already an author with this ROR ID.
ROR IDs have to be distinct.",
call. = FALSE)
}
orig <- set_author_field(
orig,
wh$index,
"comment",
add_ror_to_comment(orig[wh$index]$comment,
ror)
)
self$set_authors(orig)
}



idesc_del_author <- function(self, private, given, family, email, role,
comment, orcid = NULL) {
comment, orcid = NULL, ror = NULL) {

check_author_args(given, family, email, role, comment, orcid)
check_author_args(given, family, email, role, comment, orcid, ror)

orig <- idesc_get_authors(self, private, ensure = FALSE)
wh <- search_for_author(
orig, given = given, family = family, email = email,
comment = comment, orcid = orcid
comment = comment, orcid = orcid,
ror = ror
)

if (length(wh$index) == 0) {
Expand All @@ -275,15 +333,16 @@


idesc_del_role <- function(self, private, role, given, family, email,
comment, orcid = NULL) {
comment, orcid = NULL, ror = NULL) {

stopifnot(is.character(role))
check_author_args(given, family, email, role = NULL, comment, orcid)
check_author_args(given, family, email, role = NULL, comment, orcid, ror)

orig <- idesc_get_authors(self, private, ensure = FALSE)
wh <- search_for_author(
orig, given = given, family = family, email = email, comment = comment,
orcid = orcid, role = NULL
orcid = orcid, role = NULL,
ror = ror
)

for (w in wh$index) {
Expand All @@ -298,7 +357,7 @@
self$set_authors(orig)
}


# no ROR as argument since an organization cannot be a maintainer
idesc_change_maintainer <- function(self, private, given, family, email,
comment, orcid = NULL) {
check_author_args(given, family, email, role = NULL, comment, orcid)
Expand Down Expand Up @@ -438,3 +497,9 @@
comment
}

# helper to add or replace ROR in comment
add_ror_to_comment <- function(comment, ror){

comment["ROR"] <- ror
comment
}
35 changes: 22 additions & 13 deletions R/description.R
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ desc <- function(cmd = NULL, file = NULL, text = NULL, package = NULL) {
#'
#' ```r
#' description$add_author(given = NULL, family = NULL, email = NULL,
#' role = NULL, comment = NULL, orcid = NULL)
#' role = NULL, comment = NULL, orcid = NULL, ror = NULL)
#' description$add_me(role = "ctb", comment = NULL, orcid = NULL)
#' description$add_author_gh(username, role = "ctb", comment = NULL, orcid = NULL)
#' ```
Expand All @@ -346,7 +346,7 @@ desc <- function(cmd = NULL, file = NULL, text = NULL, package = NULL) {
#'
#' ```r
#' description$del_author(given = NULL, family = NULL, email = NULL,
#' role = NULL, comment = NULL, orcid = NULL)
#' role = NULL, comment = NULL, orcid = NULL, ror = NULL)
#' ```
#'
#' Remove an author, or multiple authors. The author(s) to be removed
Expand All @@ -357,13 +357,15 @@ desc <- function(cmd = NULL, file = NULL, text = NULL, package = NULL) {
#'
#' ```r
#' description$add_role(role, given = NULL, family = NULL, email = NULL,
#' comment = NULL, orcid = NULL)
#' comment = NULL, orcid = NULL, ror = NULL)
#' description$add_orcid(orcid, given = NULL, family = NULL, email = NULL,
#' comment = NULL, role = NULL)
#' description$add_ror(ror, given = NULL, family = NULL, email = NULL,
#' comment = NULL, role = NULL)
#' description$del_role(role, given = NULL, family = NULL, email = NULL,
#' comment = NULL, orcid = NULL)
#' comment = NULL, orcid = NULL, ror = NULL)
#' description$change_maintainer(given = NULL, family = NULL,
#' email = NULL, comment = NULL, orcid = NULL)
#' email = NULL, comment = NULL, orcid = NULL, ror = NULL)
#' ```
#'
#' `role` is the role to add or delete. The other arguments
Expand Down Expand Up @@ -611,30 +613,37 @@ description <- R6Class("description",
idesc_set_authors(self, private, authors),

add_author = function(given = NULL, family = NULL, email = NULL,
role = NULL, comment = NULL, orcid = NULL)
role = NULL, comment = NULL, orcid = NULL,
ror = NULL)
idesc_add_author(self, private, given, family, email, role, comment,
orcid),
orcid, ror),

add_role = function(role, given = NULL, family = NULL, email = NULL,
comment = NULL, orcid = NULL)
comment = NULL, orcid = NULL, ror = NULL)
idesc_add_role(self, private, role, given, family, email, comment,
orcid),
orcid, ror),

add_orcid = function(orcid, given = NULL, family = NULL, email = NULL,
comment = NULL, role = NULL)
idesc_add_orcid(self, private, role = role, given = given, family = family,
email = email, comment = comment,
orcid = orcid),

add_ror = function(ror, given = NULL, family = NULL, email = NULL,
comment = NULL, role = NULL)
idesc_add_ror(self, private, role = role, given = given, family = family,
email = email, comment = comment,
ror = ror),

del_author = function(given = NULL, family = NULL, email = NULL,
role = NULL, comment = NULL, orcid = NULL)
role = NULL, comment = NULL, orcid = NULL, ror = NULL)
idesc_del_author(self, private, given, family, email, role, comment,
orcid),
orcid, ror),

del_role = function(role, given = NULL, family = NULL, email = NULL,
comment = NULL, orcid = NULL)
comment = NULL, orcid = NULL, ror = NULL)
idesc_del_role(self, private, role, given, family, email, comment,
orcid),
orcid, ror),

change_maintainer = function(given = NULL, family = NULL, email = NULL,
comment = NULL, orcid = NULL)
Expand Down
27 changes: 26 additions & 1 deletion R/non-oo-api.R
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ desc_set_authors <- generate_api("set_authors")
#' @param role Role.
#' @param comment Comment.
#' @param orcid ORCID.
#' @param ror ROR ID.
#' @inheritParams desc_set
#'
#' @family Authors@R
Expand All @@ -407,16 +408,19 @@ desc_add_author <- generate_api("add_author")
#' @title Add a role to one or more authors in Authors@R, in DESCRIPTION
#'
#' @description The author(s) can be specified by a combination of the `given`,
#' `family`, `email`, `comment` and `orcid` fields.
#' `family`, `email`, `comment`, `orcid` and `ror` fields.
#' If multiple filters are specified, then all must match
#' to identify the author(s).
#' You cannot both specify `orcid` and `ror`
#' since ORCID is for individuals, ROR for organizations.
#'
#' @param role Role to add.
#' @param given Given name to filter on. Regular expression.
#' @param family Family name to filter on. Regular expression.
#' @param email Email address to filter on. Regular expression.
#' @param comment Comment field to filter on. Regular expression.
#' @param orcid ORCID field to filter on.
#' @param ror ROR field to filter on.
#' @inheritParams desc_set
#'
#' @family Authors@R
Expand Down Expand Up @@ -444,6 +448,7 @@ desc_add_role <- generate_api("add_role")

desc_add_orcid <- generate_api("add_orcid")


#' Remove one or more authors from DESCRIPTION.
#'
#' It uses the Authors@R field. The author(s) to be removed
Expand All @@ -460,6 +465,26 @@ desc_add_orcid <- generate_api("add_orcid")

desc_del_author <- generate_api("del_author")

#' @title Add an ROR to one or more authors in Authors@R, in DESCRIPTION
#'
#' @description The author(s) can be specified by a combination of the `given`,
#' `family`, `email`, `comment` and `role` fields.
#' If multiple filters are specified, then all must match
#' to identify the author(s).
#'
#' @param ror ror to add.
#' @param given Given name to filter on. Regular expression.
#' @param family Family name to filter on. Regular expression.
#' @param email Email address to filter on. Regular expression.
#' @param comment Comment field to filter on. Regular expression.
#' @param role Role field to filter on.
#' @inheritParams desc_set
#'
#' @family Authors@R
#' @export

desc_add_ror <- generate_api("add_ror")

#' @title Delete a role of an author, in DESCRIPTION
#'
#' @inherit desc_add_role description
Expand Down
2 changes: 2 additions & 0 deletions inst/WORDLIST
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Lifecycle
LinkingTo
ORCID
PBC
ROR
ror
RStudio
Renviron
behaviour
Expand Down
Loading
Loading