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.py166
1 files changed, 82 insertions, 84 deletions
diff --git a/pre_commit/languages/r.py b/pre_commit/languages/r.py
index d281102..e238365 100644
--- a/pre_commit/languages/r.py
+++ b/pre_commit/languages/r.py
@@ -10,10 +10,8 @@ from typing import Sequence
from pre_commit.envcontext import envcontext
from pre_commit.envcontext import PatchesT
from pre_commit.envcontext import UNSET
-from pre_commit.hook import Hook
from pre_commit.languages import helpers
from pre_commit.prefix import Prefix
-from pre_commit.util import clean_path_on_failure
from pre_commit.util import cmd_output_b
from pre_commit.util import win_exe
@@ -31,32 +29,22 @@ def get_env_patch(venv: str) -> PatchesT:
@contextlib.contextmanager
-def in_env(
- prefix: Prefix,
- language_version: str,
-) -> Generator[None, None, None]:
- envdir = _get_env_dir(prefix, language_version)
+def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
+ envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
with envcontext(get_env_patch(envdir)):
yield
-def _get_env_dir(prefix: Prefix, version: str) -> str:
- return prefix.path(helpers.environment_dir(ENVIRONMENT_DIR, version))
-
-
-def _prefix_if_non_local_file_entry(
- entry: Sequence[str],
- prefix: Prefix,
- src: str,
+def _prefix_if_file_entry(
+ entry: list[str],
+ prefix: Prefix,
+ *,
+ is_local: bool,
) -> Sequence[str]:
- if entry[1] == '-e':
+ if entry[1] == '-e' or is_local:
return entry[1:]
else:
- if src == 'local':
- path = entry[1]
- else:
- path = prefix.path(entry[1])
- return (path,)
+ return (prefix.path(entry[1]),)
def _rscript_exec() -> str:
@@ -67,7 +55,7 @@ def _rscript_exec() -> str:
return os.path.join(r_home, 'bin', win_exe('Rscript'))
-def _entry_validate(entry: Sequence[str]) -> None:
+def _entry_validate(entry: list[str]) -> None:
"""
Allowed entries:
# Rscript -e expr
@@ -81,20 +69,23 @@ def _entry_validate(entry: Sequence[str]) -> None:
raise ValueError('You can supply at most one expression.')
elif len(entry) > 2:
raise ValueError(
- 'The only valid syntax is `Rscript -e {expr}`',
+ 'The only valid syntax is `Rscript -e {expr}`'
'or `Rscript path/to/hook/script`',
)
-def _cmd_from_hook(hook: Hook) -> tuple[str, ...]:
- entry = shlex.split(hook.entry)
- _entry_validate(entry)
+def _cmd_from_hook(
+ prefix: Prefix,
+ entry: str,
+ args: Sequence[str],
+ *,
+ is_local: bool,
+) -> tuple[str, ...]:
+ cmd = shlex.split(entry)
+ _entry_validate(cmd)
- return (
- *entry[:1], *RSCRIPT_OPTS,
- *_prefix_if_non_local_file_entry(entry, hook.prefix, hook.src),
- *hook.args,
- )
+ cmd_part = _prefix_if_file_entry(cmd, prefix, is_local=is_local)
+ return (cmd[0], *RSCRIPT_OPTS, *cmd_part, *args)
def install_environment(
@@ -102,55 +93,54 @@ def install_environment(
version: str,
additional_dependencies: Sequence[str],
) -> None:
- env_dir = _get_env_dir(prefix, version)
- with clean_path_on_failure(env_dir):
- os.makedirs(env_dir, exist_ok=True)
- shutil.copy(prefix.path('renv.lock'), env_dir)
- shutil.copytree(prefix.path('renv'), os.path.join(env_dir, 'renv'))
-
- r_code_inst_environment = f"""\
- prefix_dir <- {prefix.prefix_dir!r}
- options(
- repos = c(CRAN = "https://cran.rstudio.com"),
- renv.consent = TRUE
- )
- source("renv/activate.R")
- renv::restore()
- activate_statement <- paste0(
- 'suppressWarnings({{',
- 'old <- setwd("', getwd(), '"); ',
- 'source("renv/activate.R"); ',
- 'setwd(old); ',
- 'renv::load("', getwd(), '");}})'
- )
- writeLines(activate_statement, 'activate.R')
- is_package <- tryCatch(
- {{
- path_desc <- file.path(prefix_dir, 'DESCRIPTION')
- suppressWarnings(desc <- read.dcf(path_desc))
- "Package" %in% colnames(desc)
- }},
- error = function(...) FALSE
- )
- if (is_package) {{
- renv::install(prefix_dir)
- }}
- """
-
- cmd_output_b(
- _rscript_exec(), '--vanilla', '-e',
- _inline_r_setup(r_code_inst_environment),
- cwd=env_dir,
+ env_dir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
+ os.makedirs(env_dir, exist_ok=True)
+ shutil.copy(prefix.path('renv.lock'), env_dir)
+ shutil.copytree(prefix.path('renv'), os.path.join(env_dir, 'renv'))
+
+ r_code_inst_environment = f"""\
+ prefix_dir <- {prefix.prefix_dir!r}
+ options(
+ repos = c(CRAN = "https://cran.rstudio.com"),
+ renv.consent = TRUE
+ )
+ source("renv/activate.R")
+ renv::restore()
+ activate_statement <- paste0(
+ 'suppressWarnings({{',
+ 'old <- setwd("', getwd(), '"); ',
+ 'source("renv/activate.R"); ',
+ 'setwd(old); ',
+ 'renv::load("', getwd(), '");}})'
)
- if additional_dependencies:
- r_code_inst_add = 'renv::install(commandArgs(trailingOnly = TRUE))'
- with in_env(prefix, version):
- cmd_output_b(
- _rscript_exec(), *RSCRIPT_OPTS, '-e',
- _inline_r_setup(r_code_inst_add),
- *additional_dependencies,
- cwd=env_dir,
- )
+ writeLines(activate_statement, 'activate.R')
+ is_package <- tryCatch(
+ {{
+ path_desc <- file.path(prefix_dir, 'DESCRIPTION')
+ suppressWarnings(desc <- read.dcf(path_desc))
+ "Package" %in% colnames(desc)
+ }},
+ error = function(...) FALSE
+ )
+ if (is_package) {{
+ renv::install(prefix_dir)
+ }}
+ """
+
+ cmd_output_b(
+ _rscript_exec(), '--vanilla', '-e',
+ _inline_r_setup(r_code_inst_environment),
+ cwd=env_dir,
+ )
+ if additional_dependencies:
+ r_code_inst_add = 'renv::install(commandArgs(trailingOnly = TRUE))'
+ with in_env(prefix, version):
+ cmd_output_b(
+ _rscript_exec(), *RSCRIPT_OPTS, '-e',
+ _inline_r_setup(r_code_inst_add),
+ *additional_dependencies,
+ cwd=env_dir,
+ )
def _inline_r_setup(code: str) -> str:
@@ -166,11 +156,19 @@ def _inline_r_setup(code: str) -> str:
def run_hook(
- hook: Hook,
+ prefix: Prefix,
+ entry: str,
+ args: Sequence[str],
file_args: Sequence[str],
+ *,
+ is_local: bool,
+ require_serial: bool,
color: bool,
) -> tuple[int, bytes]:
- with in_env(hook.prefix, hook.language_version):
- return helpers.run_xargs(
- hook, _cmd_from_hook(hook), file_args, color=color,
- )
+ cmd = _cmd_from_hook(prefix, entry, args, is_local=is_local)
+ return helpers.run_xargs(
+ cmd,
+ file_args,
+ require_serial=require_serial,
+ color=color,
+ )