diff --git a/DESCRIPTION b/DESCRIPTION index ad04dba..0606ee6 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,11 +1,11 @@ Package: TAF Version: 4.3.0 -Date: 2024-02-28 +Date: 2024-06-11 Title: Transparent Assessment Framework for Reproducible Research Authors@R: c(person("Arni", "Magnusson", role=c("aut","cre"), email="thisisarni@gmail.com"), person("Colin", "Millar", role="aut"), - person("Alexandros", "Kokkalis", role="ctb"), person("Iago", "Mosqueira", role="ctb"), + person("Alexandros", "Kokkalis", role="ctb"), person("Ibrahim", "Umar", role="ctb"), person("Hjalte", "Parner", role="ctb")) Imports: grDevices, lattice, methods, stats, tools, utils diff --git a/NEWS.md b/NEWS.md index 05ae4d0..c4598ab 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,7 @@ -# TAF 4.3.0 (2024-02-28) +# TAF 4.3.0 (2024-06-11) + +* Added function check.software() to check global package versions - an + administrative tool for special cases. Code contributed by Iago Mosqueira. * Added function ddim() to show the data dimensions of a table. diff --git a/R/TAF-package.R b/R/TAF-package.R index a25f5d7..0b15b2f 100644 --- a/R/TAF-package.R +++ b/R/TAF-package.R @@ -90,6 +90,7 @@ #' } #' \emph{Administrative tools, rarely used in scripts:} #' \tabular{ll}{ +#' \code{\link{check.software}} \tab check global package versions\cr #' \code{\link{clean.data}} \tab clean boot data\cr #' \code{\link{clean.library}} \tab clean TAF library\cr #' \code{\link{clean.software}} \tab clean TAF software\cr diff --git a/R/check.software.R b/R/check.software.R index 39e0cf3..8adeaf8 100644 --- a/R/check.software.R +++ b/R/check.software.R @@ -1,60 +1,85 @@ -#' Check versions with those in SOFTWARE.bib +#' Check SOFTWARE.bib Against Global Packages #' -#' Compare installed and required package versions +#' Compare versions declared in \verb{SOFTWARE.bib} with packages installed in +#' the global R library. #' -#' @details -#' A SOFTWARE.bib file can be use to record what package versions a certain -#' analysis expects. Those available in the running session can be compared -#' with those listed in the file. A warning is printed if the former are -#' earlier that the later. +#' @param full whether to return full data frame as output. #' -#' @return TRUE or FALSE if available packages match those required or not. +#' @return +#' Logical vector (or data frame if \verb{full = TRUE}) indicating which +#' installed packages are \dfn{ready}, i.e., at least as new as the version +#' required in \verb{SOFTWARE.bib}. #' -#' @name check.software -#' @rdname check.software +#' A warning is raised if any installed packages are older than required. #' -#' @seealso [draft.software()] -#' @keywords classes +#' @note +#' Generally, TAF installs R packages that are declared in \verb{SOFTWARE.bib} +#' inside the TAF library (\verb{boot/library}). This guarantees that the right +#' versions of packages are installed for the analysis. The \code{taf.library} +#' function is then used to load packages from the TAF library. +#' +#' In special cases, however, it might be useful to compare the versions of +#' packages declared in \verb{SOFTWARE.bib} against packages that are installed +#' in the global R library, outside the TAF library. +#' +#' @seealso +#' \code{\link{taf.boot}} and \code{\link{taf.library}} are the general tools to +#' install and load packages of the correct version in the TAF library. +#' +#' \code{\link{update.packages}} can be used to update packages in the general R +#' library to the newest version available on CRAN. +#' +#' @examples +#' \dontrun{ +#' check.software() +#' check.software(full) +#' } #' #' @importFrom utils compareVersion #' @importFrom utils packageVersion #' #' @export -check.software <- function() { - +check.software <- function(full=FALSE) +{ # GET bib file - bibfile <- (file.path(boot.dir(), "SOFTWARE.bib")) + bibfile <- file.path(boot.dir(), "SOFTWARE.bib") # CHECK file exists if(!file.exists(bibfile)) - stop(paste0("File ", boot.dir(), "/SOFTWARE.bib does not exist")) + stop(paste0("file ", boot.dir(), "/SOFTWARE.bib does not exist")) # READ bib file entries <- taf.sources("software") - # EXTRACT versions - versions <- sapply(entries, '[[', 'version') - - # COMPARE with available in session: 0 if equal, -1 is too old, 1 if newer - comparison <- unlist(lapply(setNames(nm=names(versions)), function(x) - compareVersion(as.character(packageVersion(x)), versions[x]))) + # EXTRACT required version + req <- sapply(entries, "[[", "version") + req <- gsub("[,; ].*", "", req) # remove text after comma/semicolon/space + out <- data.frame(Package=names(req), Required=req, row.names=NULL) - # FIND those too old - toold <- comparison == -1 - - # WARN if any SOFTWARE.bib:versions > available - if(any(toold)) { - - msg <- lapply(names(toold)[toold], function(x) - paste0(x, ": ", packageVersion(x), " installed but ", versions[x], - " required\n")) - - warning(strwrap(msg, prefix="; ", initial="")) - - invisible(FALSE) + # COMPARE with installed version + out$Installed <- NA + out$Ready <- NA + for(i in seq_len(nrow(out))) + { + inst <- try(as.character(packageVersion(out$Package[i])), silent=TRUE) + out$Installed[i] <- if(inherits(inst, "try-error")) NA else inst + cmp <- compareVersion(out$Required[i], out$Installed[i]) + out$Ready[i] <- if(is.na(out$Installed[i])) NA else cmp < 1 + } - } else { - invisible(TRUE) + # WARN if any packages are obsolete (Installed < Required) + obs <- which(!out$Ready) + if(length(obs) > 0) + { + txt <- paste(out$Package[obs], out$Installed[obs], "installed but", + out$Required[obs], "required", collapse="; ") + warning(txt) } + + # RETURN data frame or vector + if(full) + out + else + invisible(setNames(out$Ready, out$Package)) } diff --git a/man/TAF-package.Rd b/man/TAF-package.Rd index 37ffd9d..20fcb1b 100644 --- a/man/TAF-package.Rd +++ b/man/TAF-package.Rd @@ -91,6 +91,7 @@ scientific applications. } \emph{Administrative tools, rarely used in scripts:} \tabular{ll}{ + \code{\link{check.software}} \tab check global package versions\cr \code{\link{clean.data}} \tab clean boot data\cr \code{\link{clean.library}} \tab clean TAF library\cr \code{\link{clean.software}} \tab clean TAF software\cr diff --git a/man/check.software.Rd b/man/check.software.Rd index 25adfad..02fc35d 100644 --- a/man/check.software.Rd +++ b/man/check.software.Rd @@ -2,23 +2,45 @@ % Please edit documentation in R/check.software.R \name{check.software} \alias{check.software} -\title{Check versions with those in SOFTWARE.bib} +\title{Check SOFTWARE.bib Against Global Packages} \usage{ -check.software() +check.software(full = FALSE) +} +\arguments{ +\item{full}{whether to return full data frame as output.} } \value{ -TRUE or FALSE if available packages match those required or not. +Logical vector (or data frame if \verb{full = TRUE}) indicating which +installed packages are \dfn{ready}, i.e., at least as new as the version +required in \verb{SOFTWARE.bib}. + +A warning is raised if any installed packages are older than required. } \description{ -Compare installed and required package versions +Compare versions declared in \verb{SOFTWARE.bib} with packages installed in +the global R library. +} +\note{ +Generally, TAF installs R packages that are declared in \verb{SOFTWARE.bib} +inside the TAF library (\verb{boot/library}). This guarantees that the right +versions of packages are installed for the analysis. The \code{taf.library} +function is then used to load packages from the TAF library. + +In special cases, however, it might be useful to compare the versions of +packages declared in \verb{SOFTWARE.bib} against packages that are installed +in the global R library, outside the TAF library. +} +\examples{ +\dontrun{ +check.software() +check.software(full) } -\details{ -A SOFTWARE.bib file can be use to record what package versions a certain -analysis expects. Those available in the running session can be compared -with those listed in the file. A warning is printed if the former are -earlier that the later. + } \seealso{ -[draft.software()] +\code{\link{taf.boot}} and \code{\link{taf.library}} are the general tools to +install and load packages of the correct version in the TAF library. + +\code{\link{update.packages}} can be used to update packages in the general R +library to the newest version available on CRAN. } -\keyword{classes} diff --git a/tests/Examples/TAF-Ex.Rout.save b/tests/Examples/TAF-Ex.Rout.save index 077acbe..1decdb9 100644 --- a/tests/Examples/TAF-Ex.Rout.save +++ b/tests/Examples/TAF-Ex.Rout.save @@ -1,7 +1,7 @@ -R version 4.3.2 (2023-10-31) -- "Eye Holes" -Copyright (C) 2023 The R Foundation for Statistical Computing -Platform: x86_64-pc-linux-gnu (64-bit) +R version 4.4.0 (2024-04-24) -- "Puppy Cup" +Copyright (C) 2024 The R Foundation for Statistical Computing +Platform: x86_64-pc-linux-gnu R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. @@ -207,6 +207,26 @@ Type 'q()' to quit R. > > > cleanEx() +> nameEx("check.software") +> ### * check.software +> +> flush(stderr()); flush(stdout()) +> +> ### Name: check.software +> ### Title: Check SOFTWARE.bib Against Global Packages +> ### Aliases: check.software +> +> ### ** Examples +> +> ## Not run: +> ##D check.software() +> ##D check.software(full) +> ## End(Not run) +> +> +> +> +> cleanEx() > nameEx("clean") > ### * clean > @@ -1818,7 +1838,7 @@ detaching ‘package:lattice’ > options(digits = 7L) > base::cat("Time elapsed: ", proc.time() - base::get("ptime", pos = 'CheckExEnv'),"\n") -Time elapsed: 0.236 0.001 0.236 0 0 +Time elapsed: 0.216 0.008 0.225 0 0 > grDevices::dev.off() null device 1