Skip to content
Open
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@ Suggests:
testthat,
webmockr,
jsonlite
RoxygenNote: 7.2.3
RoxygenNote: 7.3.2
VignetteBuilder: knitr
Config/testthat/edition: 3
4 changes: 4 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ S3method(pillar_shaft,pkg_metric_error)
S3method(pkg_assess,list_of_pkg_ref)
S3method(pkg_assess,pkg_ref)
S3method(pkg_assess,tbl_df)
S3method(pkg_metric_export,list)
S3method(pkg_metric_export,tbl_df)
S3method(pkg_score,list_of_pkg_metric)
S3method(pkg_score,tbl_df)
S3method(print,pkg_ref)
Expand Down Expand Up @@ -116,6 +118,8 @@ export(get_assessments)
export(metric_score)
export(pkg_assess)
export(pkg_metric)
export(pkg_metric_export)
export(pkg_metric_import)
export(pkg_ref)
export(pkg_score)
export(score_error_NA)
Expand Down
89 changes: 89 additions & 0 deletions R/pkg_metric_export.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Converts snake_case to PascalCase
to_pascal_case <- function(x) {
words <- strsplit(x, "_")[[1]]
paste0(toupper(substring(words, 1, 1)), substring(words, 2), collapse = "")
}

#' Flatten scored metrics to DCF-style key-value pairs
#'
#' `pkg_metric_export()` converts scored package metrics into a flat list of
#' character strings in DCF (Debian Control File) style. Each metric is
#' written as a line in the form `Metric<Name>: <value>`, where `<Name>` is the
#' PascalCase transformation of the metric name.
#'
#' This is useful for exporting results from `pkg_score()` into formats that
#' require simple key-value structures.
#'
#' @param x A `tbl_df` or `list` returned by `pkg_score()`, containing scored
#' `pkg_metric` values. The input may come from `pkg_score.tbl_df()` (for
#' many packages) or `pkg_score.list_of_pkg_metric()` (for a single package).
#' @param ... additional arguments unused
#'
#' @return A character vector, where each element is a DCF-style line
#' representing one scored metric (e.g., `"MetricHasNews: 1"`).
#' @seealso pkg_metric_import
#' @examples
#' \dontrun{
#' # For a single package
#' metrics <- pkg_score(pkg_assess(pkg_ref("riskmetric")))[[1]]
#' pkg_metric_export(metrics)
#'
#' # For a data frame of packages
#' library(dplyr)
#' scores <- pkg_score(pkg_assess(as_tibble(pkg_ref("riskmetric"))))
#' pkg_metric_export(scores[1, ]) # flatten first package's results
#' }
#'
#' @export
pkg_metric_export <- function(x, ...) {
UseMethod("pkg_metric_export")
}

#' @export
pkg_metric_export.list <- function(x, file = "PACKAGES", ...) {
record <- list()
for (name in names(x)) {
pascal_name <- paste0("Metric", to_pascal_case(name))
value <- as.character(x[[name]][1])

# Replace NA values with "NA" string
record[[pascal_name]] <- ifelse(is.na(value), "NA", value)
}

# Convert to one-row data frame
df <- as.data.frame(record, stringsAsFactors = FALSE)
write.dcf(df, file = file)
df
}

#' @export
pkg_metric_export.tbl_df <- function(x, file = "PACKAGES", ...) {
x <- x[, setdiff(names(x), "pkg_ref")]

records <- lapply(seq_len(nrow(x)), function(i) {
row <- x[i, , drop = FALSE]
record <- list()

for (name in names(row)) {
value <- as.character(row[[name]])

# Replace NA values with "NA" string
value <- ifelse(is.na(row[[name]]), "NA", value)

# Leave Package and Version untouched
if (name %in% c("package", "version")) {
pascal_name <- paste0(toupper(substring(name, 1, 1)), substring(name, 2))
record[[pascal_name]] <- value
} else {
pascal_name <- paste0("Metric", to_pascal_case(name))
record[[pascal_name]] <- value
}
}

record
})

df <- do.call(rbind.data.frame, lapply(records, as.data.frame, stringsAsFactors = FALSE))
write.dcf(df, file = file)
df
}
15 changes: 15 additions & 0 deletions R/pkg_metric_import.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#' Import metrics
#'
#' @param file (`character`) Path to the file to import.
#'
#' @returns The object in the same format and class as generated by riskmetric.
#' @export
#' @seealso pkg_metric_export()
pkg_metric_import <- function(file) {
if (!file.exists(file)) {
stop("Please provide a path to a file.")
}
dcf <- read.dcf(file)
dcf <- as.data.frame(dcf)
dcf
}
26 changes: 13 additions & 13 deletions man/pkg_assess.Rd

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

45 changes: 45 additions & 0 deletions man/pkg_metric_export.Rd

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

20 changes: 20 additions & 0 deletions man/pkg_metric_import.Rd

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

2 changes: 1 addition & 1 deletion man/riskmetric.Rd

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

Loading