Skip to content

Commit

Permalink
Finish cff_read()
Browse files Browse the repository at this point in the history
  • Loading branch information
dieghernan committed Feb 19, 2024
1 parent c0d7d63 commit c1beb0e
Show file tree
Hide file tree
Showing 11 changed files with 334 additions and 44 deletions.
3 changes: 0 additions & 3 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,6 @@ references:
email: [email protected]
orcid: https://orcid.org/0000-0002-4035-0289
year: '2024'
identifiers:
- type: url
value: https://arxiv.org/abs/1403.2805
version: '>= 1.7.2'
- type: software
title: jsonvalidate
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export(cff_parse_person_bibtex)
export(cff_read)
export(cff_read_bib)
export(cff_read_cff_citation)
export(cff_read_citation)
export(cff_read_description)
export(cff_schema_definitions_entity)
export(cff_schema_definitions_person)
Expand Down
157 changes: 153 additions & 4 deletions R/cff_read.R
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,33 @@
#' @param authors_roles Roles to be considered as authors of the package when
#' generating the [`cff`][cff-class] object.
#' @param encoding Encoding to be assumed for `path`. See [readLines()].
#' @param meta A list of package metadata as obtained by
#' [utils::packageDescription()] or `NULL` (the default). See **Details**.
#' @param ... Arguments to be passed to other functions.
#'
#' @return A [`cff`][cff-class] object.
#' @return
#' A [`cff`][cff-class] object. In the case of [cff_read_cff_citation()] and
#' [cff_read_description()] a full and (potentially) valid `cff` object.
#'
#' In the case of [cff_read_bib()] and [cff_read_citation()], the result is
#' the `cff` version of a [bibentry()] object (i.e. a bibliographic reference),
#' that can be used to complement another `cff` object.
#'
#'
#' @references
#'
#' R Core Team (2023). _Writing R Extensions_.
#' <https://cran.r-project.org/doc/manuals/r-release/R-exts.html>
#'
#' @details
#'
#' Section 1.9 CITATION files of *Writing R Extensions* (R Core Team 2023)
#' specifies how to create dynamic `CITATION` files using `meta` object, hence
#' the `meta` argument in [cff_read_citation()] may be needed for reading
#' some files correctly.
#'
#' @examples
#' TODO
#'
cff_read <- function(path, ...) {
if (length(path) > 1) {
Expand All @@ -53,6 +76,7 @@ cff_read <- function(path, ...) {
"cff_citation" = cff_read_cff_citation(path, ...),
"description" = cff_read_description(path, ...),
"bib" = cff_read_bib(path, ...),
"citation" = cff_read_citation(path, ...),
NULL
)

Expand All @@ -62,6 +86,15 @@ cff_read <- function(path, ...) {
#' @export
#' @rdname cff_read
cff_read_cff_citation <- function(path, ...) {
if (!file.exists(path)) {
cli::cli_abort(
paste(
"{.file {path}} does not exist. ",
"Check the {.file {dirname(path)}} directory"
)
)
}

cffobj <- yaml::read_yaml(path)
new_cff(cffobj)
}
Expand All @@ -71,6 +104,15 @@ cff_read_cff_citation <- function(path, ...) {
cff_read_description <- function(path, cff_version = "1.2.0",
gh_keywords = TRUE,
authors_roles = c("aut", "cre"), ...) {
if (!file.exists(path)) {
cli::cli_abort(
paste(
"{.file {path}} does not exist. ",
"Check the {.file {dirname(path)}} directory"
)
)
}

pkg <- desc::desc(path)
pkg$coerce_authors_at_r()

Expand Down Expand Up @@ -108,14 +150,71 @@ cff_read_description <- function(path, cff_version = "1.2.0",

#' @export
#' @rdname cff_read
cff_read_cff_citation <- function(path, ...) {
cffobj <- yaml::read_yaml(path)
new_cff(cffobj)
cff_read_citation <- function(path, meta = NULL, ...) {
if (!file.exists(path)) {
cli::cli_abort(
paste(
"{.file {path}} does not exist. ",
"Check the {.file {dirname(path)}} directory"
)
)
}

if (!any(is.null(meta), inherits(meta, "packageDescription"))) {
# nolint start
# Object for cli only
ex <- packageDescription("cffr")
# nolint end

cli::cli_alert_warning(
paste0(
"{.arg meta} should be {.val NULL} or {.obj_type_friendly {ex}}",
" not {.obj_type_friendly {meta}}. Using {.arg meta = NULL}"
)
)
meta <- NULL
}

new_meta <- clean_package_meta(meta)
the_cit <- try(utils::readCitationFile(path, meta = new_meta), silent = TRUE)

# If error then new try
if (inherits(the_cit, "try-error")) {
cli::cli_alert_warning(
paste0(
"It was not possible to read {.file {path}} with the {.arg meta} ",
"provided. Trying with {.code packageDescription('base')}"
)
)
new_meta <- packageDescription("base")
the_cit <- try(utils::readCitationFile(path, meta = new_meta),
silent = TRUE
)
# nocov start
if (inherits(the_cit, "try-error")) {
cli::cli_alert_danger(
"Can't read {.file path}, returning {.val NULL}"
)
return(NULL)
}
# nocov end
}
tocff <- cff_parse_citation(the_cit)
new_cff(tocff)
}

#' @export
#' @rdname cff_read
cff_read_bib <- function(path, encoding = "UTF-8", ...) {
if (!file.exists(path)) {
cli::cli_abort(
paste(
"{.file {path}} does not exist. ",
"Check the {.file {dirname(path)}} directory"
)
)
}

# nocov start
if (!requireNamespace("bibtex", quietly = TRUE)) {
msg <- paste0(
Expand Down Expand Up @@ -156,3 +255,53 @@ guess_type_file <- function(path) {
)
)
}

#' Parse and clean data from DESCRIPTION to create metadata
#' @noRd
clean_package_meta <- function(meta) {
if (!inherits(meta, "packageDescription")) {
return(NULL)
}

# Convert to a desc object

# First write to a dcf file
tmp <- tempfile("DESCRIPTION")
meta_unl <- unclass(meta)
write.dcf(meta_unl, tmp)
pkg <- desc::desc(tmp)
pkg$coerce_authors_at_r()
# Extract package data
meta <- pkg$get(desc::cran_valid_fields)

# Clean missing and drop empty fields
meta <- drop_null(lapply(meta, clean_str))

# Check encoding
if (!is.null(meta$Encoding)) {
meta <- lapply(meta, iconv, from = meta$Encoding, to = "UTF-8")
} else {
meta$Encoding <- "UTF-8"
}
unlink(tmp, force = TRUE)
meta
}

# For testing, packageDescription object from desc
test_meta <- function(x) {
src <- x
my_meta <- desc::desc(src)

# As list
my_meta_l <- my_meta$get(desc::cran_valid_fields)
my_meta_l <- as.list(my_meta_l)
v_nas <- vapply(my_meta_l, is.na, logical(1))

my_meta_l <- my_meta_l[!v_nas]
meta_proto <- packageDescription("cffr")

class(my_meta_l) <- class(meta_proto)
attr(my_meta_l, "file") <- x

my_meta_l
}
27 changes: 6 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ file and the `CITATION` file (if present) of your package. Note that
**cffr** works best if your package pass
`R CMD check/devtools::check()`.

As per 2024-02-16 there are at least 240 repos on GitHub using **cffr**.
As per 2024-02-19 there are at least 261 repos on GitHub using **cffr**.
[Check them out
here](https://github.com/search?q=cffr%20path%3A**%2FCITATION.cff&type=code).

Expand Down Expand Up @@ -385,9 +385,6 @@ test <- cff_create("rmarkdown")
email: [email protected]
orcid: https://orcid.org/0000-0002-4035-0289
year: '2024'
identifiers:
- type: url
value: https://arxiv.org/abs/1403.2805
- type: software
title: knitr
abstract: 'knitr: A General-Purpose Package for Dynamic Report Generation in R'
Expand Down Expand Up @@ -753,18 +750,6 @@ test <- cff_create("rmarkdown")
given-names: Davis
email: [email protected]
year: '2024'
- type: software
title: cleanrmd
abstract: 'cleanrmd: Clean Class-Less ''R Markdown'' HTML Documents'
notes: Suggests
url: https://pkg.garrickadenbuie.com/cleanrmd/
repository: https://CRAN.R-project.org/package=cleanrmd
authors:
- family-names: Aden-Buie
given-names: Garrick
email: [email protected]
orcid: https://orcid.org/0000-0002-7111-0077
year: '2024'
- type: software
title: withr
abstract: 'withr: Run Code ''With'' Temporarily Modified Global State'
Expand Down Expand Up @@ -903,9 +888,9 @@ for more info.

<div id="ref-codemeta" class="csl-entry">

Boettiger, Carl, and Maëlle Salmon. 2021a. *<span
class="nocase">codemeta</span>: A Smaller <span
class="nocase">codemetar</span> Package*.
Boettiger, Carl, and Maëlle Salmon. 2021a.
*<span class="nocase">codemeta</span>: A Smaller
<span class="nocase">codemetar</span> Package*.
<https://CRAN.R-project.org/package=codemeta>.

</div>
Expand All @@ -926,8 +911,8 @@ Among Citation Formats*.

<div id="ref-citation22" class="csl-entry">

Dietrich, Jan Philipp, and Waldir Leoncio. 2022. *<span
class="nocase">citation</span>: Software Citation Tools*.
Dietrich, Jan Philipp, and Waldir Leoncio. 2022.
*<span class="nocase">citation</span>: Software Citation Tools*.

</div>

Expand Down
4 changes: 2 additions & 2 deletions codemeta.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"name": "R",
"url": "https://r-project.org"
},
"runtimePlatform": "R version 4.3.2 (2023-10-31)",
"runtimePlatform": "R version 4.3.2 (2023-10-31 ucrt)",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
Expand Down Expand Up @@ -200,7 +200,7 @@
},
"isPartOf": "https://ropensci.org",
"keywords": ["attribution", "citation", "credit", "citation-files", "cff", "metadata", "r", "r-package", "citation-file-format", "rstats", "ropensci", "cran"],
"fileSize": "1030.282KB",
"fileSize": "918.861KB",
"citation": [
{
"@type": "ScholarlyArticle",
Expand Down
Binary file modified data/cran_to_spdx.rda
Binary file not shown.
2 changes: 1 addition & 1 deletion inst/schemaorg.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"runtimePlatform": "R version 4.3.2 (2023-10-31)",
"runtimePlatform": "R version 4.3.2 (2023-10-31 ucrt)",
"version": "0.5.0.9000"
}
27 changes: 25 additions & 2 deletions man/cff_read.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit c1beb0e

Please sign in to comment.