@@ -16,6 +16,11 @@ pkg <- class_pkg <- new_class(
1616 # necessary data dependencies to be evaluated.
1717 data = class_environment ,
1818
19+ # logs (not user-facing)
20+ # A mutable environment, stores output logs captured using the `evaluate`
21+ # package. Should contain an entry for each value in `@data`.
22+ logs = class_environment ,
23+
1924 # ' @param resource [`resource`] (often a [`multi_resource`]), providing the
2025 # ' resources to be used for deriving packages data. If a
2126 # ' [`multi_resource`], the order of resources determines the precedence of
@@ -62,13 +67,25 @@ pkg <- class_pkg <- new_class(
6267 new_object(
6368 .parent = S7 :: S7_object(),
6469 data = new.env(parent = emptyenv()),
70+ logs = new.env(parent = emptyenv()),
6571 metrics = list (),
6672 resource = resource ,
6773 permissions = policy @ permissions
6874 )
6975 }
7076)
7177
78+ method(convert , list (class_character , class_pkg )) <-
79+ function (from , to , ... ) {
80+ if (endsWith(tolower(from ), " .rds" )) {
81+ convert(readRDS(from ), class_pkg )
82+ } else if (grepl(" \\ bPackage:" , from [[1L ]])) {
83+ pkg_from_dcf(from , ... )
84+ } else {
85+ pkg(from , ... )
86+ }
87+ }
88+
7289# ' Generate Random Package(s)
7390# '
7491# ' Create a package object to simulate metric derivation. When generating a
@@ -179,6 +196,8 @@ random_repo <- function(..., path = tempfile("repo")) {
179196# ' @param x [`pkg`] object to derive data for
180197# ' @param name `character(1L)` field name for the data to derive
181198# ' @param ... Additional arguments unused
199+ # ' @param logs `logical(1L)` flag indicating whether console output should be
200+ # ' captured during execution.
182201# ' @param .raise `logical(1L)` flag indicating whether errors should be raised
183202# ' or captured. This flag is not intended to be set directly, it is exposed
184203# ' so that recursive calls can raise lower-level errors while capturing them
@@ -189,7 +208,13 @@ random_repo <- function(..., path = tempfile("repo")) {
189208# '
190209# ' @keywords internal
191210# ' @include utils_err.R
192- get_pkg_data <- function (x , name , ... , .raise = .state $ raise ) {
211+ get_pkg_data <- function (
212+ x ,
213+ name ,
214+ ... ,
215+ logs = opt(" logs" ),
216+ .raise = .state $ raise
217+ ) {
193218 # RStudio, when trying to produce completions,will try to evaluate our lazy
194219 # list elements. Intercept those calls and return only the existing values.
195220 if (is_rs_rpc_get_completions_call()) {
@@ -213,7 +238,19 @@ get_pkg_data <- function(x, name, ..., .raise = .state$raise) {
213238 assert_permissions(required_permissions , x @ permissions )
214239 assert_suggests(required_suggests )
215240
216- data <- pkg_data_derive(pkg = x , field = name , ... )
241+ if (logs ) {
242+ capture <- capture_pkg_data_derive(pkg = x , field = name , ... )
243+ data <- capture $ data
244+ x @ logs [[name ]] <- capture $ logs
245+
246+ # re-throw error after storing logs if one was produced
247+ if (inherits(data , " error" )) {
248+ stop(data )
249+ }
250+ } else {
251+ data <- pkg_data_derive(pkg = x , field = name , ... )
252+ }
253+
217254 if (! identical(info @ data_class , class_any )) {
218255 data <- convert(data , info @ data_class )
219256 }
@@ -382,31 +419,59 @@ as.data.frame.list_of_pkg <- function(x, ...) {
382419}
383420
384421# ' @include utils_dcf.R
385- method(from_dcf , list (class_character , class_pkg )) <-
386- function (x , to , ... ) {
387- dcf <- from_dcf(x , class_any )
422+ method(convert , list (class_list , class_pkg )) <-
423+ function (from , to , ... ) {
388424 resource <- unknown_resource(
389- package = dcf [[1 , " Package" ]],
390- version = dcf [[1 , " Version" ]],
391- md5 = if (" MD5sum" %in% colnames(dcf )) {
392- dcf [[1 , " MD5sum" ]]
393- } else {
394- NA_character_
395- }
425+ package = from $ name %|| % from $ Package ,
426+ version = from $ version %|| % from $ Version ,
427+ md5 = from $ MD5sum %|| % NA_character_
396428 )
397429
398430 data <- new.env(parent = emptyenv())
431+ for (name in names(from )) {
432+ # recover gracefully from unknown fieldnames
433+ info <- tryCatch(pkg_data_info(name ), error = function (e ) NULL )
434+ if (is.null(info )) {
435+ next
436+ }
437+
438+ data [[name ]] <- metric_coerce(from [[name ]], info @ data_class )
439+ }
440+
441+ pkg <- pkg(resource )
442+ pkg @ data <- data
443+
444+ pkg
445+ }
446+
447+ # ' @include utils_dcf.R
448+ method(from_dcf , list (class_character , class_pkg )) <-
449+ function (x , to , ... ) {
450+ dcf <- from_dcf(x , class_any )
451+
452+ data <- list ()
453+ data $ name <- dcf [[1 , " Package" ]]
454+ data $ version <- dcf [[1 , " Version" ]]
455+ data $ md5 <- if (" MD5sum" %in% colnames(dcf )) {
456+ dcf [[1 , " MD5sum" ]]
457+ } else {
458+ NA_character_
459+ }
460+
399461 prefix <- " Metric/"
400462 for (name in colnames(dcf )[startsWith(colnames(dcf ), prefix )]) {
401463 field <- sub(prefix , " " , name )
402- info <- pkg_data_info(field )
464+
465+ # recover gracefully from unknown fieldnames
466+ info <- tryCatch(pkg_data_info(field ), error = function (e ) NULL )
467+ if (is.null(info )) {
468+ next
469+ }
470+
403471 val <- dcf [[1 , name ]]
404472 val <- metric_coerce(val , info @ data_class )
405473 data [[field ]] <- val
406474 }
407475
408- pkg <- pkg(resource )
409- pkg @ data <- data
410-
411- pkg
476+ convert(data , class_pkg )
412477 }
0 commit comments