Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
8fc6da2
Increment version number to 0.2.2.9000
villegar Aug 21, 2026
ade4258
Update documentation for enrich_argument and add new cases to capture…
villegar Aug 28, 2026
d5c0ca9
Include column in the returned object by safe_output
villegar Aug 28, 2026
4b5df2d
Add command level ID for the logs, this helps keeping track of comman…
villegar Sep 2, 2026
ba405a8
Update code to include ASSIGN operations in the output logs
villegar Sep 3, 2026
64e6079
Update code used to update unique command IDs
villegar Sep 3, 2026
6712624
Bump version number to next patch release
villegar Sep 3, 2026
48cd326
Update local bindings
villegar Sep 9, 2026
b62b031
Update test expected output
villegar Sep 9, 2026
cdd3350
Suppress warnings when checking minimum version of Opal, as instances…
villegar Sep 11, 2026
6d2d05e
Validate that symbol_id is not empty inside the resolve_provenance he…
villegar Sep 11, 2026
4ec020b
Capture RESOLVE operations in the logs
villegar Sep 24, 2026
b205960
Add filter to handle logs without AGGREGATE operations
villegar Sep 24, 2026
d039dc3
Add filter to handle empty symbol registry
villegar Sep 24, 2026
74ef9bd
Update processing of symbols_tbl to handle scenarios without ASSIGN o…
villegar Sep 24, 2026
735853f
Add new tests to check the handle of RESOLVE operations
villegar Sep 24, 2026
8686eee
Add comment for upcoming release
villegar Sep 24, 2026
051afbc
Bump version of roxygen2
villegar Sep 24, 2026
71d76c6
Update NEWS for release
villegar Sep 24, 2026
091c277
Update wording on NEWS
villegar Sep 24, 2026
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
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: dsROCrate
Title: 'DataSHIELD' RO-Crate Governance Functions
Version: 0.2.2
Version: 0.2.3
Authors@R: c(
person(given = "Roberto",
family = "Villegas-Diaz",
Expand Down Expand Up @@ -59,4 +59,4 @@ Depends:
VignetteBuilder: knitr
URL: https://github.com/FederatedMethods/dsROCrate
BugReports: https://github.com/FederatedMethods/dsROCrate/issues
Config/roxygen2/version: 8.0.0
Config/roxygen2/version: 8.1.0
27 changes: 27 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
# dsROCrate 0.2.3

## New Features

* `safe_output()` now preserves Opal 6.0 `RESOLVE` operations independently of `ASSIGN` operations, including the resolved symbol and source table/resource for provenance. `RESOLVE` entries are retained even when no matching `ASSIGN` follows (e.g., a failed resolution). This is only enabled when the server reports Opal >= 6.0.
* Every entry in the audit log tibble returned via `safe_output()` (and written to the `_mappings.csv` file) now has a unique `id` (UUID), and the tibble gains a `column` field recording the column referenced by a function call argument (e.g. `D$LAB_TSC`), where applicable.

## Improvements

* Function-call arguments supplied as R expressions (e.g. `D$LAB_TSC`) are now resolved back to the single registered symbol they reference, along with the referenced column. Expressions that reference several symbols, or none that are registered, are returned unchanged.
* Audit log entries are now ordered by their original log-entry order and then timestamp, and operation IDs are regenerated as UUIDs.
* Symbol IDs generated by `safe_symbol()` are now plain UUIDs, without the previous `"symbol-"` prefix.

## Bug fixes

* Fixed `safe_output()` failing when an audit session contains no `ASSIGN` operations: an empty, correctly typed symbols table is now used.
* Fixed `safe_output()` failing when no function calls could be reconstructed from the logs: an empty, correctly typed calls table is now used.
* `safe_output()` no longer injects a placeholder row (`ds_profile = "-999999"`) into the parsed logs; a zero-row typed tibble is used to guarantee the `ds_profile` column exists instead.
* Fixed `resolve_dependencies()` failing on an empty symbol registry, and `resolve_provenance()` failing when given an `NA` symbol ID. Both now return an empty tibble.
* `validate_backend_version()` (opal method) no longer emits warnings from `utils::compareVersion()`.

## Internal Changes

* Added tests covering `safe_output()` with `RESOLVE` and `ASSIGN` operations, and `RESOLVE` operations without `ASSIGN`; updated `as.data.frame.safe_call()` test for the new `id` column.
* Declared additional local bindings in `safe_output()` to silence `R CMD check` notes about undefined global variables.
* Updated roxygen2 documentation for `enrich_argument()` and `safe_call()`; regenerated with roxygen2 8.1.0.

# dsROCrate 0.2.2

## Bug fixes
Expand Down
2 changes: 1 addition & 1 deletion R/backend-opal.R
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ is_audit_con.opal <- function(x, ...) {

#' @export
validate_backend_version.opal <- function(x, ..., minimum = "5.7.2") {
if (utils::compareVersion(x$version, minimum) < 0) {
if (suppressWarnings(utils::compareVersion(x$version, minimum)) < 0) {
stop(
sprintf(
"Opal >= %s is required, but server version is %s.",
Expand Down
35 changes: 33 additions & 2 deletions R/safe-call-utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
#' @param timestamp Timestamp to map the symbol details.
#' @param session String with session ID.
#'
#' @returns `safe_reference` object.
#' @returns `safe_reference` object, or the original argument when no
#' registered symbol can be resolved.
#' @keywords internal
#'
#' @noRd
Expand All @@ -14,20 +15,50 @@ enrich_argument <- function(arg, registry, timestamp, session) {
return(arg)
}

# attempt solving the argument as a direct symbol reference
symbol <- resolve_symbol(
registry,
symbol = arg,
timestamp = timestamp,
session = session
)

if (!is.null(symbol)) {
return(safe_reference(symbol = symbol$symbol, symbol_id = symbol$id))
}

# if the argument isn't itself a symbol, try interpreting it as an R expr.
refs <- tryCatch(
find_symbols(arg),
error = function(e) NULL
)

if (is.null(refs) || !length(refs)) {
return(arg)
}

# if multiple symbols are found, return original obkect
if (length(refs) != 1L) {
return(arg)
}

ref <- refs[[1]]

symbol <- resolve_symbol(
registry,
symbol = ref$symbol,
timestamp = timestamp,
session = session
)

if (is.null(symbol)) {
return(arg)
}

safe_reference(
symbol = symbol$symbol,
symbol_id = symbol$id
symbol_id = symbol$id,
column = ref$column
)
}

Expand Down
4 changes: 4 additions & 0 deletions R/safe-call.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#' @export
as.data.frame.safe_call <- function(x, ...) {
data.frame(
id = x$id,
timestamp = format(x$created_at, '%Y-%m-%dT%H:%M:%S'),
user = x$user,
r_cmd = x$original,
Expand All @@ -19,6 +20,7 @@ as.data.frame.safe_call <- function(x, ...) {
#' @param namespace Function's namespace.
#' @param fx Function's name.
#' @param args List with arguments.
#' @param id Unique call ID.
#' @param ... Additional arguments.
#'
#' @returns New `safe_call` object.
Expand All @@ -31,6 +33,7 @@ new_safe_call <- function(
namespace,
fx,
args,
id = uuid::UUIDgenerate(),
...
) {
stopifnot(is.character(original))
Expand All @@ -39,6 +42,7 @@ new_safe_call <- function(

structure(
list(
id = id,
original = original,
package = package,
namespace = namespace,
Expand Down
4 changes: 2 additions & 2 deletions R/safe-symbol-utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ resolve_dependencies <- function(expr, registry) {
# find symbols for the given expression
refs <- find_symbols(expr)

if (is.null(refs)) {
if (is.null(refs) || !length(registry$symbols)) {
return(tibble::tibble())
}

Expand Down Expand Up @@ -102,7 +102,7 @@ resolve_provenance <- function(symbol_id, registry, visited = character()) {
# local bindings
id <- NULL

if (symbol_id %in% visited) {
if (symbol_id %in% visited || is.na(symbol_id)) {
return(tibble::tibble())
}

Expand Down
2 changes: 1 addition & 1 deletion R/safe-symbol.R
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ new_safe_symbol <- function(
session = NA_character_,
action = NA_character_,
metadata = list(),
id = paste0("symbol-", uuid::UUIDgenerate())
id = uuid::UUIDgenerate()
) {
stopifnot(is.character(symbol))
stopifnot(length(symbol) == 1)
Expand Down
Loading
Loading