mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-04-15 01:51:46 +04:00
avoid quoting and escaping while installing R hooks by writing code to tempfile instead of execute R code inline
This commit is contained in:
parent
c389ac0ba8
commit
cd09c3525e
1 changed files with 35 additions and 16 deletions
|
|
@ -4,6 +4,8 @@ import contextlib
|
||||||
import os
|
import os
|
||||||
import shlex
|
import shlex
|
||||||
import shutil
|
import shutil
|
||||||
|
import tempfile
|
||||||
|
import textwrap
|
||||||
from typing import Generator
|
from typing import Generator
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
|
|
@ -21,6 +23,19 @@ get_default_version = lang_base.basic_get_default_version
|
||||||
health_check = lang_base.basic_health_check
|
health_check = lang_base.basic_health_check
|
||||||
|
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def _r_code_in_tempfile(code: str) -> Generator[str, None, None]:
|
||||||
|
"""
|
||||||
|
To avoid quoting and escaping issues, avoid `Rscript [options] -e {expr}`
|
||||||
|
but use `Rscript [options] path/to/file_with_expr.R`
|
||||||
|
"""
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
|
fname = os.path.join(tmpdir, 'script.R')
|
||||||
|
with open(fname, 'w') as f:
|
||||||
|
f.write(_inline_r_setup(textwrap.dedent(code)))
|
||||||
|
yield fname
|
||||||
|
|
||||||
|
|
||||||
def get_env_patch(venv: str) -> PatchesT:
|
def get_env_patch(venv: str) -> PatchesT:
|
||||||
return (
|
return (
|
||||||
('R_PROFILE_USER', os.path.join(venv, 'activate.R')),
|
('R_PROFILE_USER', os.path.join(venv, 'activate.R')),
|
||||||
|
|
@ -129,20 +144,19 @@ def install_environment(
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
cmd_output_b(
|
with _r_code_in_tempfile(r_code_inst_environment) as f:
|
||||||
_rscript_exec(), '--vanilla', '-e',
|
cmd_output_b(_rscript_exec(), '--vanilla', f, cwd=env_dir)
|
||||||
_inline_r_setup(r_code_inst_environment),
|
|
||||||
cwd=env_dir,
|
|
||||||
)
|
|
||||||
if additional_dependencies:
|
if additional_dependencies:
|
||||||
r_code_inst_add = 'renv::install(commandArgs(trailingOnly = TRUE))'
|
r_code_inst_add = 'renv::install(commandArgs(trailingOnly = TRUE))'
|
||||||
with in_env(prefix, version):
|
with in_env(prefix, version):
|
||||||
cmd_output_b(
|
with _r_code_in_tempfile(r_code_inst_add) as f:
|
||||||
_rscript_exec(), *RSCRIPT_OPTS, '-e',
|
cmd_output_b(
|
||||||
_inline_r_setup(r_code_inst_add),
|
_rscript_exec(), *RSCRIPT_OPTS,
|
||||||
*additional_dependencies,
|
f,
|
||||||
cwd=env_dir,
|
*additional_dependencies,
|
||||||
)
|
cwd=env_dir,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _inline_r_setup(code: str) -> str:
|
def _inline_r_setup(code: str) -> str:
|
||||||
|
|
@ -150,11 +164,16 @@ def _inline_r_setup(code: str) -> str:
|
||||||
Some behaviour of R cannot be configured via env variables, but can
|
Some behaviour of R cannot be configured via env variables, but can
|
||||||
only be configured via R options once R has started. These are set here.
|
only be configured via R options once R has started. These are set here.
|
||||||
"""
|
"""
|
||||||
with_option = f"""\
|
with_option = [
|
||||||
options(install.packages.compile.from.source = "never", pkgType = "binary")
|
textwrap.dedent("""\
|
||||||
{code}
|
options(
|
||||||
"""
|
install.packages.compile.from.source = "never",
|
||||||
return with_option
|
pkgType = "binary"
|
||||||
|
)
|
||||||
|
"""),
|
||||||
|
code,
|
||||||
|
]
|
||||||
|
return '\n'.join(with_option)
|
||||||
|
|
||||||
|
|
||||||
def run_hook(
|
def run_hook(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue