Skip to content
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

Major documentation overhaul - Main vignette and core function updates #80

Merged
merged 4 commits into from
Dec 20, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
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: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
.DS_Store

inst/doc
docs

.Rproj.user
.Rhistory
.RData
.Ruserdata
.html
docs
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Imports:
rvest,
memoise,
janitor
RoxygenNote: 6.1.1
RoxygenNote: 7.0.2
Suggests:
knitr,
rmarkdown,
Expand Down
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ S3method("[",pkg_ref)
S3method("[<-",pkg_ref)
S3method("[[",pkg_ref)
S3method("[[<-",pkg_ref)
S3method(.DollarNames,pkg_ref)
S3method(as_pkg_ref,character)
S3method(as_pkg_ref,default)
S3method(as_pkg_ref,pkg_ref)
Expand All @@ -21,6 +22,7 @@ S3method(format,pkg_metric)
S3method(format,pkg_metric_error)
S3method(format,pkg_missing)
S3method(format,pkg_ref)
S3method(names,pkg_ref)
S3method(pillar_shaft,list_of_pkg_metric)
S3method(pillar_shaft,list_of_pkg_ref)
S3method(pillar_shaft,pkg_metric_error)
Expand Down
121 changes: 81 additions & 40 deletions R/assess.R
Original file line number Diff line number Diff line change
@@ -1,11 +1,81 @@
#' Helper for creating a roxygen header from template for assess_* functions
#'
#' @param name the name of the assessment, assuming naming conventions are
#' followed
#' @param return_type an optional added commentary about the return type of the
#' assessment function
#'
#' @return roxygen section template for assess family functions
#'
#' @examples
#' \dontrun{
#' #' @eval roxygen_assess_family(
#' "has_news",
#' "an integer value indicating the number of discovered NEWS files")
#' }
#'
roxygen_assess_family <- function(name,
return_type = "an atomic assessment result") {

assess_func <- sprintf("assess_%s", name)
score_func <- sprintf("score.pkg_metric_%s", name)

if (!assess_func %in% getNamespaceExports(utils::packageName()) ||
!score_func %in% getNamespaceExports(utils::packageName())) {
stop(sprintf(paste0(
"All assess_* functions must have a corresponding score.* method ",
"implemented.\n\n",
"To remove build errors, ensure that the following functions are ",
"implemented:\n\n",
" %s()\n",
" %s()\n")),
assess_func,
score_func)
}

c("@param x a \\code{pkg_ref} package reference object",
"@param ... additional arguments passed on to S3 methods, rarely used",
sprintf("@return a \\code{pkg_metric} containing %s", return_type),
"@family \\code{assess_*} functions",
sprintf("@seealso \\code{\\link{%s}}", score_func),
sprintf("@examples assess_%s(pkg_ref(\"%s\"))", name, packageName()))
}



#' Helper for creating a roxygen itemized list for assess_* functions
#'
#' @return roxygen section template for assess family function catalog
#'
#' @examples
#' \dontrun{
#' #' @eval assess_family_catalog_roxygen()
#' }
#'
roxygen_assess_family_catalog <- function() {
assessments <- all_assessments()
info <- lapply(assessments, attr, "label")
missing_label <- vapply(info, is.null, logical(1L))
info[missing_label] <- names(info)[missing_label]

c("@section Assessment function catalog:",
"\\describe{",
sprintf('\\item{\\code{\\link{%s}}}{%s}', names(info), info),
"}")
}



#' A default list of assessments to perform for each package
#'
#' @return a list of assess_* functions exported from riskmetric
#'
#' @importFrom utils packageName
#' @export
all_assessments <- function() {
fs <- grep("^assess_", getNamespaceExports(utils::packageName()), value = TRUE)
fs <- grep("^assess_[^.]*$",
getNamespaceExports(utils::packageName()),
value = TRUE)
Map(getExportedValue, fs, ns = list(utils::packageName()))
}

Expand Down Expand Up @@ -40,10 +110,14 @@ use_assessments_column_names <- function(x) {



#' Function for applying assess_* family of functions to packages
#' Apply assess_* family of functions to a package reference
#'
#' @param x A single package reference object or \code{\link[tibble]{tibble}} of
#' package references to assess
#' By default, use all \code{assess_*} funtions in the \code{riskmetric}
#' namespace and produce a \code{\link[tibble]{tibble}} with one column per
#' assessment applied.
#'
#' @param x A single \code{\link{pkg_ref}} object or
#' \code{\link[tibble]{tibble}} of package references to assess
#' @param assessments A list of assessment functions to apply to each package
#' reference. By default, a list of all exported assess_* functions from the
#' riskmetric package.
Expand All @@ -57,7 +131,9 @@ use_assessments_column_names <- function(x) {
#' metric objects returned when the assessment was called with the associated
#' pacakge reference.
#'
#' @seealso as_tibble.pkg_ref
#' @eval roxygen_assess_family_catalog()
#'
#' @family \code{assess_*} functions
#'
#' @importFrom tibble as_tibble
#' @importFrom vctrs new_list_of
Expand Down Expand Up @@ -89,38 +165,3 @@ assess <- function(x, assessments = all_assessments(), ...,

x
}



#' Helper for creating a roxygen header from template for assess_* functions
#'
#' @param name the name of the assessment, assuming naming conventions are
#' followed
#' @param return_type an optional added commentary about the return type of the
#' assessment function
#'
#' @return roxygen section template for assess family functions
#'
#' @examples
#' \dontrun{
#' #' @eval assess_family_roxygen(
#' "has_news",
#' "an integer value indicating the number of discovered NEWS files")
#' }
#'
assess_family_roxygen <- function(name,
return_type = "an atomic assessment result") {

assess_func <- sprintf("assess_%s", name)
score_func <- sprintf("score.pkg_metric_%s", name)

stopifnot(assess_func %in% getNamespaceExports(utils::packageName()))
stopifnot(score_func %in% getNamespaceExports(utils::packageName()))

c("@param x a \\code{pkg_ref} package reference object",
"@param ... additional arguments passed on to S3 methods, rarely used",
sprintf("@return a \\code{pkg_metric} containing %s", return_type),
"@family \\code{assess_*} functions",
sprintf("@seealso \\code{\\link{%s}}", score_func),
sprintf("@examples assess_%s(pkg_ref(\"%s\"))", name, packageName()))
}
2 changes: 1 addition & 1 deletion R/assess_export_help.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#' Assess a package for availability of documentation for exported values
#'
#' @eval assess_family_roxygen(
#' @eval roxygen_assess_family(
#' "export_help",
#' "a logical vector indicating existence of documentation for each namespace export")
#'
Expand Down
2 changes: 1 addition & 1 deletion R/assess_has_news.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#' Assess a package for the presence of a NEWS file
#'
#' @eval assess_family_roxygen(
#' @eval roxygen_assess_family(
#' "has_news",
#' "an integer value indicating the number of discovered NEWS files")
#'
Expand Down
2 changes: 1 addition & 1 deletion R/assess_license.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#' Assess a package for an up-to-date NEWS file
#'
#' @eval assess_family_roxygen(
#' @eval roxygen_assess_family(
#' "license",
#' "a string indicating the license under which the package is released")
#'
Expand Down
2 changes: 1 addition & 1 deletion R/assess_news_current.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#' Assess a package for an up-to-date NEWS file
#'
#' @eval assess_family_roxygen(
#' @eval roxygen_assess_family(
#' "news_current",
#' "a logical vector indicating whether each discovered NEWS file is up-to-date")
#'
Expand Down
84 changes: 82 additions & 2 deletions R/pkg_ref_cache.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,83 @@
#' S3 generic to calculate a `pkg_ref` field
#'
#' Reactively retrieve and cache `pkg_ref` metadata
#'
#' @section Caching Details:
#' \subsection{\code{pkg_ref} class fields}{
#' The \code{pkg_ref} class structures an environment with special handling
#' for indexing into the \code{pkg_ref} class using the \code{$} or \code{[[}
#' operators. For all intents and purposes, the \code{pkg_ref} class is works
#' conceptually similar to a lazy, immutable \code{list}, and uses the
#' \code{pkg_ref_cache} function internally to lazily retrieve package
#' reference fields.
#' }
#' \subsection{Lazy metadata caching}{
#' Laziness in a \code{pkg_ref} object refers to the delayed evaluation of the
#' contents of its fields. Since some metadata is time or computationally
#' intensive to retrieve, and unnessary for some assessments, we want to avoid
#' that retrieval until it is needed.
#'
#' The first time that a field is accessed within a \code{pkg_ref} object
#' \code{x}, a corresponding \code{pkg_ref_cache} S3 generic is called. For
#' example, when \code{x$description} is first accessed, the \code{pkg_ref}
#' object uses the function \code{pkg_ref_cache.description} to attempt to
#' retrieve the contents of the corresponding \code{DESCRIPTION} file.
#'
#' Often, the way that this data is collected might be different depending on
#' the subclass of the \code{pkg_ref}. In the case of the \code{description}
#' metadata, a reference to a local install might be able to read in a local
#' file directly, whereas a reference to a remote source of metadata might
#' require first downloading the file. For this reason, many
#' \code{pkg_ref_cache.*} functions are themselves S3 generics that dispatch
#' on the class of the \code{pkg_ref} object, allowing for divergent behaviors
#' for different source of package metadata.
#' }
#' \subsection{\code{pkg_ref} field immutability}{
#' Once a field has been calculated, its value is immutable. This behavior was
#' chosen because of the long time frame over which package metadata changes,
#' rendering it unnecessary to continually reevaluate fields each time they
#' are accesssed.
#'
#' This means that within an assessment, a given field for a package will only
#' ever be calculated once and preserved for downstream use.
#' }
#'
#' @examples
#' # implementing a new field called "first_letter" that is consistently derived
#' # across all pkg_ref objects:
#'
#' pkg_ref_cache.first_letter <- function(x, name, ...) {
#' substring(x$name, 1, 1)
#' }
#'
#' x <- pkg_ref("riskmetric")
#' x$first_letter
#'
#'
#'
#' # implementing a new field called "subclass_enum" that dispatches on
#' # the subclass of the pkg_ref object:
#'
#' pkg_ref_cache.subclass_enum <- function(x, name, ...) {
#' UseMethod("pkg_ref_cache.subclass_enum")
#' }
#'
#' pkg_ref_cache.subclass_enum.pkg_ref <- function(x, name, ...) {
#' 0
#' }
#'
#' pkg_ref_cache.subclass_enum.pkg_install <- function(x, name, ...) {
#' 1
#' }
#'
#' x$subclass_enum
#'
#' @rdname riskmetric_metadata_caching
#' @name pkg_ref_cache
NULL



#' A helper function for retrieving a list of available fields, identified based
#' on implementation of a pkg_ref_cache method for a given class.
#'
Expand All @@ -17,8 +97,6 @@ available_pkg_ref_fields <- function(x) {



#' S3 function to extend a package reference with new fields
#'
#' @param x a package reference object
#' @param name the name of the field that needs to be cached
#' @param ... additional arguments used for computing cached values
Expand All @@ -30,6 +108,8 @@ available_pkg_ref_fields <- function(x) {
#'
#' @family package reference cache
#'
#' @rdname riskmetric_metadata_caching
#'
pkg_ref_cache <- function(x, name, ..., .class = as.character(name)) {
UseMethod("pkg_ref_cache", structure(list(), class = .class))
}
4 changes: 2 additions & 2 deletions R/pkg_ref_cache_help.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ pkg_ref_cache.help <- function(x, name, ...) {

#' @importFrom tools Rd_db parseLatex
pkg_ref_cache.help.pkg_install <- function(x, name, ...) {
lapply(tools::Rd_db(package = x$name), tools::parseLatex)
tools::Rd_db(package = x$name)
}



#' @importFrom tools Rd_db parseLatex
pkg_ref_cache.help.pkg_source <- function(x, name, ...) {
lapply(tools::Rd_db(dir = x$path), tools::parseLatex)
tools::Rd_db(dir = x$path)
}
Loading