#!/usr/bin/env Rscript # Install the latest tagged bincraft release, resolved dynamically, so the CI # workflows and the build-one image never pin a hardcoded version (no more # editing `@vX.Y.Z` in many places on every release). # # Run with the R whose library should receive bincraft: # Rscript local/install-bincraft.R # or, to target a specific R from a shell loop: # "$RBIN" -q -e 'source("local/install-bincraft.R")' # # How it works: list the remote tags with `git ls-remote` (no token needed for # the public repo), keep the `vX.Y.Z` release tags, pick the highest version, # and install it with uvr via `local/uvr-install.sh`. uvr is idempotent on the # git ref, so re-running keeps the package when it is already current and only # updates when a newer tag ships. Filtering/sorting is done in R (not via git's # `--sort`/refspec) so behaviour is identical across git versions and # `system2()` argument handling. repo_url <- Sys.getenv( "BINCRAFT_GIT_URL", unset = "https://codefloe.com/rpkgs/bincraft.git" ) # GIT_TERMINAL_PROMPT=0 keeps a non-interactive run from hanging on auth. refs <- system2( "git", c("ls-remote", "--tags", repo_url), stdout = TRUE, stderr = FALSE, env = "GIT_TERMINAL_PROMPT=0" ) tags <- sub(".*refs/tags/", "", refs) tags <- tags[!grepl("\\^\\{\\}$", tags)] # drop dereferenced "...^{}" lines tags <- grep("^v[0-9]", tags, value = TRUE) # only vX.Y.Z release tags if (length(tags) == 0L) { stop( "Could not resolve any bincraft release tag from ", repo_url, call. = FALSE ) } latest <- tags[order(package_version(sub("^v", "", tags)), decreasing = TRUE)][ 1L ] message(sprintf("Installing latest bincraft release: %s", latest)) # uvr addresses Forgejo repos as `forgejo::host/owner/repo@ref` rather than as a # git URL, so drop the scheme and the trailing `.git` from `repo_url`. spec <- sprintf( "forgejo::%s@%s", sub("\\.git$", "", sub("^[a-z]+://", "", repo_url)), latest ) # `local/uvr-install.sh` when run from the repo root, `/work/local/` in the # build-one image, which copies the two scripts into a flatter layout. helper <- Sys.getenv("UVR_INSTALL_SH", unset = "") if (!nzchar(helper)) { candidates <- c("local/uvr-install.sh", "/work/local/uvr-install.sh") found <- candidates[file.exists(candidates)] if (length(found) == 0L) { stop("Could not locate uvr-install.sh; set UVR_INSTALL_SH", call. = FALSE) } helper <- found[1L] } # Point uvr at the R running this script and at the library it would install # into, so the per-R-minor passes in the build pipelines (which call a different # Rscript with R_LIBS_USER pointed elsewhere) target their own R and library. Sys.setenv( UVR_R_BIN = file.path(R.home("bin"), "R"), UVR_TARGET_LIB = .libPaths()[1L] ) status <- system2(helper, shQuote(spec)) if (!identical(status, 0L)) { stop( sprintf("uvr failed to install %s (exit %s)", spec, status), call. = FALSE ) } message(sprintf( "bincraft %s installed (%s)", as.character(utils::packageVersion("bincraft")), latest ))