summaryrefslogtreecommitdiffstats
path: root/pre_commit/languages/r.py
diff options
context:
space:
mode:
Diffstat (limited to 'pre_commit/languages/r.py')
-rw-r--r--pre_commit/languages/r.py81
1 files changed, 70 insertions, 11 deletions
diff --git a/pre_commit/languages/r.py b/pre_commit/languages/r.py
index 93b62bd..c75a308 100644
--- a/pre_commit/languages/r.py
+++ b/pre_commit/languages/r.py
@@ -14,17 +14,78 @@ from pre_commit.envcontext import envcontext
from pre_commit.envcontext import PatchesT
from pre_commit.envcontext import UNSET
from pre_commit.prefix import Prefix
+from pre_commit.util import cmd_output
from pre_commit.util import cmd_output_b
from pre_commit.util import win_exe
ENVIRONMENT_DIR = 'renv'
RSCRIPT_OPTS = ('--no-save', '--no-restore', '--no-site-file', '--no-environ')
get_default_version = lang_base.basic_get_default_version
-health_check = lang_base.basic_health_check
+
+
+def _execute_vanilla_r_code_as_script(
+ code: str, *,
+ prefix: Prefix, version: str, args: Sequence[str] = (), cwd: str,
+) -> str:
+ with in_env(prefix, version), _r_code_in_tempfile(code) as f:
+ _, out, _ = cmd_output(
+ _rscript_exec(), *RSCRIPT_OPTS, f, *args, cwd=cwd,
+ )
+ return out.rstrip('\n')
+
+
+def _read_installed_version(envdir: str, prefix: Prefix, version: str) -> str:
+ return _execute_vanilla_r_code_as_script(
+ 'cat(renv::settings$r.version())',
+ prefix=prefix, version=version,
+ cwd=envdir,
+ )
+
+
+def _read_executable_version(envdir: str, prefix: Prefix, version: str) -> str:
+ return _execute_vanilla_r_code_as_script(
+ 'cat(as.character(getRversion()))',
+ prefix=prefix, version=version,
+ cwd=envdir,
+ )
+
+
+def _write_current_r_version(
+ envdir: str, prefix: Prefix, version: str,
+) -> None:
+ _execute_vanilla_r_code_as_script(
+ 'renv::settings$r.version(as.character(getRversion()))',
+ prefix=prefix, version=version,
+ cwd=envdir,
+ )
+
+
+def health_check(prefix: Prefix, version: str) -> str | None:
+ envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
+
+ r_version_installation = _read_installed_version(
+ envdir=envdir, prefix=prefix, version=version,
+ )
+ r_version_current_executable = _read_executable_version(
+ envdir=envdir, prefix=prefix, version=version,
+ )
+ if r_version_installation in {'NULL', ''}:
+ return (
+ f'Hooks were installed with an unknown R version. R version for '
+ f'hook repo now set to {r_version_current_executable}'
+ )
+ elif r_version_installation != r_version_current_executable:
+ return (
+ f'Hooks were installed for R version {r_version_installation}, '
+ f'but current R executable has version '
+ f'{r_version_current_executable}'
+ )
+
+ return None
@contextlib.contextmanager
-def _r_code_in_tempfile(code: str) -> Generator[str, None, None]:
+def _r_code_in_tempfile(code: str) -> Generator[str]:
"""
To avoid quoting and escaping issues, avoid `Rscript [options] -e {expr}`
but use `Rscript [options] path/to/file_with_expr.R`
@@ -44,7 +105,7 @@ def get_env_patch(venv: str) -> PatchesT:
@contextlib.contextmanager
-def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
+def in_env(prefix: Prefix, version: str) -> Generator[None]:
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
with envcontext(get_env_patch(envdir)):
yield
@@ -147,16 +208,14 @@ def install_environment(
with _r_code_in_tempfile(r_code_inst_environment) as f:
cmd_output_b(_rscript_exec(), '--vanilla', f, cwd=env_dir)
+ _write_current_r_version(envdir=env_dir, prefix=prefix, version=version)
if additional_dependencies:
r_code_inst_add = 'renv::install(commandArgs(trailingOnly = TRUE))'
- with in_env(prefix, version):
- with _r_code_in_tempfile(r_code_inst_add) as f:
- cmd_output_b(
- _rscript_exec(), *RSCRIPT_OPTS,
- f,
- *additional_dependencies,
- cwd=env_dir,
- )
+ _execute_vanilla_r_code_as_script(
+ code=r_code_inst_add, prefix=prefix, version=version,
+ args=additional_dependencies,
+ cwd=env_dir,
+ )
def _inline_r_setup(code: str) -> str: