actions-sync icon indicating copy to clipboard operation
actions-sync copied to clipboard

Add workflow to check with minimally available versions

Open krlmlr opened this issue 1 year ago • 0 comments

Similarly to https://github.com/krlmlr/minver, but checking is perhaps simpler.

Draft, but isn't fully correct yet because pak installs the most recent version of dependencies, not their minimum versions. This or a similar procedure must be applied recursively to all dependencies.

It's difficult to solve in pkgdepends because we also need to check if the package is installable to begin with.

pak::pak("desc")

deps <- desc::desc_get_deps()

deps <- deps[deps$package != "R", ]
base_packages <- rownames(installed.packages(.libPaths()[[2]]))
deps <- deps[!(deps$package %in% base_packages), ]

cran <- rownames(available.packages())
deps <- deps[deps$package %in% cran, ]

deps$version <- gsub("[>]= +", "", deps$version)

history <- Map(deps$package, deps$version, f = function(package, version) {
  hist <- pak::pkg_history(package)
  if (version != "*") {
    valid <- (package_version(hist$Version) >= package_version(version))
    hist <- hist[valid, ]
  }
  hist
})
names(history) <- deps$package

unlink("lib", force = TRUE, recursive = TRUE)
dir.create("lib")

for (i in seq_along(history)) {
  package <- names(history)[[i]]
  hist <- history[[i]]
  inst <- installed.packages("lib")
  if (package %in% rownames(inst)) {
    if (package_version(inst[package, "Version"]) >= package_version(hist$Version[[1]])) {
      hist <- data.frame()
    }
  }

  success <- TRUE
  for (j in seq_len(nrow(hist))) {
    success <- FALSE
    message(hist$Version[[j]])
    try(pak::pak(ask = FALSE, lib = normalizePath("lib/"), paste0(package, "@", hist$Version[[j]])))
    if (dir.exists(file.path("lib", package))) {
      success <- TRUE
      break
    }
  }
  
  stopifnot(success)
}

krlmlr avatar Apr 02 '23 08:04 krlmlr