#' Create a local conda environment manually
#'
#' Manually create a local conda environment with versioning and thread safety.
#' This is intended for use in analysis workflows rather than package development.
#'
#' @param dir String containing the path to a directory in which the local environment is to be stored.
#' @param ... Further arguments to pass to \code{\link{setupBasiliskEnv}}.
#'
#' @return String containing a path to the newly created environment, or to an existing environment if one was previously created.
#' This can be used in \code{\link{basiliskRun}}.
#'
#' @author Aaron Lun
#'
#' @details
#' This function is intended for end users who wish to use the \pkg{basilisk} machinery for coordinating one or more Python environments in their analysis workflows.
#' It can be inserted into, e.g., Rmarkdown reports to automatically provision and cache an environment on first compilation,
#' which will be automatically re-used in later compilations.
#' Some care is taken to ensure that the cached environment is refreshed when \pkg{basilisk} is updated,
#' and that concurrent access to the environment is done safely.
#'
#' @examples
#' if (.Platform$OS.type != "windows") {
#' tmploc <- file.path(tempdir(), "my_package_C")
#' tmp <- createLocalBasiliskEnv(tmploc, packages="pandas==1.4.3")
#' basiliskRun(env=tmp, fun=function() {
#' X <- reticulate::import("pandas"); X$`__version__`
#' }, testload="pandas")
#' }
#'
#' @export
#' @importFrom basilisk.utils installConda
#' @importFrom dir.expiry lockDirectory unlockDirectory touchDirectory
createLocalBasiliskEnv <- function(dir, ...) {
installConda()
dir.create(dir, showWarnings=FALSE)
dir <- normalizePath(dir)
version <- as.character(packageVersion("basilisk"))
envpath <- file.path(dir, version)
# Decide whether we want to destroy things.
do.destroy <- destroyOldVersions()
# Locking the environment directory; this ensures we will wait for
# any concurrently running installations to finish. Do NOT assign
# the existence of envpath to a variable for re-use in the
# conditional below. We want to recheck existance just in case the
# directory was created after waiting to acquire the lock.
lck <- lockDirectory(envpath, exclusive=!file.exists(envpath))
on.exit(unlockDirectory(lck, clear=do.destroy), add=TRUE, after=FALSE)
if (!file.exists(envpath)) {
setupBasiliskEnv(envpath, ...)
}
# Touching both the individual package directory _and_ the conda
# directory on successful acquisition of the path.
touchDirectory(envpath)
envpath
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.