diff --git a/Changelog.md b/Changelog.md index 8d3aa6af..75658e65 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented here. ## [unreleased] - Update python, pyta and jupyter testers to allow a requirements file (#580) +- Update R tester to allow a renv.lock file (#581) ## [v2.6.0] - Update python versions in docker file (#568) diff --git a/server/autotest_server/testers/r/lib/r_renv_setup.R b/server/autotest_server/testers/r/lib/r_renv_setup.R new file mode 100644 index 00000000..a9fe9fe8 --- /dev/null +++ b/server/autotest_server/testers/r/lib/r_renv_setup.R @@ -0,0 +1,18 @@ +# Script to install dependencies for R tester environment using a renv.lock file. + +# Install renv if not already installed +if (!("renv" %in% rownames(installed.packages()))) { + install.packages("renv") +} +library(renv) + +# Set the path for the renv.lock file and the env_dir directory +lockfile <- commandArgs(trailingOnly = TRUE)[1] +env_dir <- commandArgs(trailingOnly = TRUE)[2] + +if (!file.exists(lockfile)) { + stop("renv.lock file not found: ", lockfile) +} + +# Initialize the renv environment and restore dependencies from the lockfile +renv::restore(lockfile = lockfile, library = env_dir) diff --git a/server/autotest_server/testers/r/settings_schema.json b/server/autotest_server/testers/r/settings_schema.json index a1810d60..9b9d786d 100644 --- a/server/autotest_server/testers/r/settings_schema.json +++ b/server/autotest_server/testers/r/settings_schema.json @@ -14,6 +14,11 @@ "title": "R environment", "type": "object", "properties": { + "renv.lock": { + "title": "Use renv to set up environment", + "type": "boolean", + "default": false + }, "requirements": { "title": "Package requirements", "type": "string" diff --git a/server/autotest_server/testers/r/setup.py b/server/autotest_server/testers/r/setup.py index 16ff1326..6d418582 100644 --- a/server/autotest_server/testers/r/setup.py +++ b/server/autotest_server/testers/r/setup.py @@ -5,10 +5,11 @@ def create_environment(settings_, env_dir, default_env_dir): env_data = settings_.get("env_data", {}) - req_string = env_data.get("requirements", "") + lockfile_submitted = env_data.get("renv.lock", False) os.makedirs(env_dir, exist_ok=True) env = {"R_LIBS_SITE": env_dir, "R_LIBS_USER": env_dir} + req_string = env_data.get("requirements", "") r_tester_setup = os.path.join(os.path.dirname(os.path.realpath(__file__)), "lib", "r_tester_setup.R") subprocess.run( ["Rscript", r_tester_setup, req_string], @@ -18,6 +19,17 @@ def create_environment(settings_, env_dir, default_env_dir): capture_output=True, ) + if lockfile_submitted: + renv_lock_path = os.path.join(env_dir, "../", "files", "renv.lock") + r_renv_setup = os.path.join(os.path.dirname(os.path.realpath(__file__)), "lib", "r_renv_setup.R") + if os.path.exists(renv_lock_path): + subprocess.run( + ["Rscript", r_renv_setup, renv_lock_path, env_dir], + env={**os.environ, **env}, + check=True, + text=True, + capture_output=True, + ) return {**env, "PYTHON": os.path.join(default_env_dir, "bin", "python3")}