mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-02-17 00:04:42 +04:00
add support for R via renv
This commit is contained in:
parent
b193d9e67b
commit
f1502119a2
15 changed files with 443 additions and 4 deletions
|
|
@ -26,6 +26,10 @@ jobs:
|
||||||
Write-Host "##vso[task.prependpath]C:\Strawberry\perl\site\bin"
|
Write-Host "##vso[task.prependpath]C:\Strawberry\perl\site\bin"
|
||||||
Write-Host "##vso[task.prependpath]C:\Strawberry\c\bin"
|
Write-Host "##vso[task.prependpath]C:\Strawberry\c\bin"
|
||||||
displayName: Add strawberry perl to PATH
|
displayName: Add strawberry perl to PATH
|
||||||
|
- task: PowerShell@2
|
||||||
|
inputs:
|
||||||
|
filePath: "testing/get-r.ps1"
|
||||||
|
displayName: install R
|
||||||
- template: job--python-tox.yml@asottile
|
- template: job--python-tox.yml@asottile
|
||||||
parameters:
|
parameters:
|
||||||
toxenvs: [py37]
|
toxenvs: [py37]
|
||||||
|
|
@ -42,6 +46,8 @@ jobs:
|
||||||
testing/get-swift.sh
|
testing/get-swift.sh
|
||||||
echo '##vso[task.prependpath]/tmp/swift/usr/bin'
|
echo '##vso[task.prependpath]/tmp/swift/usr/bin'
|
||||||
displayName: install swift
|
displayName: install swift
|
||||||
|
- bash: testing/get-r.sh
|
||||||
|
displayName: install R
|
||||||
- template: job--python-tox.yml@asottile
|
- template: job--python-tox.yml@asottile
|
||||||
parameters:
|
parameters:
|
||||||
toxenvs: [pypy3, py36, py37, py38, py39]
|
toxenvs: [pypy3, py36, py37, py38, py39]
|
||||||
|
|
@ -56,3 +62,5 @@ jobs:
|
||||||
testing/get-swift.sh
|
testing/get-swift.sh
|
||||||
echo '##vso[task.prependpath]/tmp/swift/usr/bin'
|
echo '##vso[task.prependpath]/tmp/swift/usr/bin'
|
||||||
displayName: install swift
|
displayName: install swift
|
||||||
|
- bash: testing/get-r.sh
|
||||||
|
displayName: install R
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ from pre_commit.languages import node
|
||||||
from pre_commit.languages import perl
|
from pre_commit.languages import perl
|
||||||
from pre_commit.languages import pygrep
|
from pre_commit.languages import pygrep
|
||||||
from pre_commit.languages import python
|
from pre_commit.languages import python
|
||||||
|
from pre_commit.languages import r
|
||||||
from pre_commit.languages import ruby
|
from pre_commit.languages import ruby
|
||||||
from pre_commit.languages import rust
|
from pre_commit.languages import rust
|
||||||
from pre_commit.languages import script
|
from pre_commit.languages import script
|
||||||
|
|
@ -52,6 +53,7 @@ languages = {
|
||||||
'perl': Language(name='perl', ENVIRONMENT_DIR=perl.ENVIRONMENT_DIR, get_default_version=perl.get_default_version, healthy=perl.healthy, install_environment=perl.install_environment, run_hook=perl.run_hook), # noqa: E501
|
'perl': Language(name='perl', ENVIRONMENT_DIR=perl.ENVIRONMENT_DIR, get_default_version=perl.get_default_version, healthy=perl.healthy, install_environment=perl.install_environment, run_hook=perl.run_hook), # noqa: E501
|
||||||
'pygrep': Language(name='pygrep', ENVIRONMENT_DIR=pygrep.ENVIRONMENT_DIR, get_default_version=pygrep.get_default_version, healthy=pygrep.healthy, install_environment=pygrep.install_environment, run_hook=pygrep.run_hook), # noqa: E501
|
'pygrep': Language(name='pygrep', ENVIRONMENT_DIR=pygrep.ENVIRONMENT_DIR, get_default_version=pygrep.get_default_version, healthy=pygrep.healthy, install_environment=pygrep.install_environment, run_hook=pygrep.run_hook), # noqa: E501
|
||||||
'python': Language(name='python', ENVIRONMENT_DIR=python.ENVIRONMENT_DIR, get_default_version=python.get_default_version, healthy=python.healthy, install_environment=python.install_environment, run_hook=python.run_hook), # noqa: E501
|
'python': Language(name='python', ENVIRONMENT_DIR=python.ENVIRONMENT_DIR, get_default_version=python.get_default_version, healthy=python.healthy, install_environment=python.install_environment, run_hook=python.run_hook), # noqa: E501
|
||||||
|
'r': Language(name='r', ENVIRONMENT_DIR=r.ENVIRONMENT_DIR, get_default_version=r.get_default_version, healthy=r.healthy, install_environment=r.install_environment, run_hook=r.run_hook), # noqa: E501
|
||||||
'ruby': Language(name='ruby', ENVIRONMENT_DIR=ruby.ENVIRONMENT_DIR, get_default_version=ruby.get_default_version, healthy=ruby.healthy, install_environment=ruby.install_environment, run_hook=ruby.run_hook), # noqa: E501
|
'ruby': Language(name='ruby', ENVIRONMENT_DIR=ruby.ENVIRONMENT_DIR, get_default_version=ruby.get_default_version, healthy=ruby.healthy, install_environment=ruby.install_environment, run_hook=ruby.run_hook), # noqa: E501
|
||||||
'rust': Language(name='rust', ENVIRONMENT_DIR=rust.ENVIRONMENT_DIR, get_default_version=rust.get_default_version, healthy=rust.healthy, install_environment=rust.install_environment, run_hook=rust.run_hook), # noqa: E501
|
'rust': Language(name='rust', ENVIRONMENT_DIR=rust.ENVIRONMENT_DIR, get_default_version=rust.get_default_version, healthy=rust.healthy, install_environment=rust.install_environment, run_hook=rust.run_hook), # noqa: E501
|
||||||
'script': Language(name='script', ENVIRONMENT_DIR=script.ENVIRONMENT_DIR, get_default_version=script.get_default_version, healthy=script.healthy, install_environment=script.install_environment, run_hook=script.run_hook), # noqa: E501
|
'script': Language(name='script', ENVIRONMENT_DIR=script.ENVIRONMENT_DIR, get_default_version=script.get_default_version, healthy=script.healthy, install_environment=script.install_environment, run_hook=script.run_hook), # noqa: E501
|
||||||
|
|
|
||||||
141
pre_commit/languages/r.py
Normal file
141
pre_commit/languages/r.py
Normal file
|
|
@ -0,0 +1,141 @@
|
||||||
|
import contextlib
|
||||||
|
import os
|
||||||
|
import shlex
|
||||||
|
import shutil
|
||||||
|
from typing import Generator
|
||||||
|
from typing import Sequence
|
||||||
|
from typing import Tuple
|
||||||
|
|
||||||
|
from pre_commit.envcontext import envcontext
|
||||||
|
from pre_commit.envcontext import PatchesT
|
||||||
|
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
|
||||||
|
|
||||||
|
ENVIRONMENT_DIR = 'renv'
|
||||||
|
get_default_version = helpers.basic_get_default_version
|
||||||
|
healthy = helpers.basic_healthy
|
||||||
|
|
||||||
|
|
||||||
|
def get_env_patch(venv: str) -> PatchesT:
|
||||||
|
return (
|
||||||
|
('R_PROFILE_USER', os.path.join(venv, 'activate.R')),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def in_env(
|
||||||
|
prefix: Prefix,
|
||||||
|
language_version: str,
|
||||||
|
) -> Generator[None, None, None]:
|
||||||
|
envdir = _get_env_dir(prefix, language_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_file_entry(
|
||||||
|
entry: Sequence[str],
|
||||||
|
prefix: Prefix,
|
||||||
|
) -> Sequence[str]:
|
||||||
|
if entry[1] == '-e':
|
||||||
|
return entry[1:]
|
||||||
|
else:
|
||||||
|
return (prefix.path(entry[1]),)
|
||||||
|
|
||||||
|
|
||||||
|
def _entry_validate(entry: Sequence[str]) -> None:
|
||||||
|
"""
|
||||||
|
Allowed entries:
|
||||||
|
# Rscript -e expr
|
||||||
|
# Rscript path/to/file
|
||||||
|
"""
|
||||||
|
if entry[0] != 'Rscript':
|
||||||
|
raise ValueError('entry must start with `Rscript`.')
|
||||||
|
|
||||||
|
if entry[1] == '-e':
|
||||||
|
if len(entry) > 3:
|
||||||
|
raise ValueError('You can supply at most one expression.')
|
||||||
|
elif len(entry) > 2:
|
||||||
|
raise ValueError(
|
||||||
|
'The only valid syntax is `Rscript -e {expr}`',
|
||||||
|
'or `Rscript path/to/hook/script`',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _cmd_from_hook(hook: Hook) -> Tuple[str, ...]:
|
||||||
|
opts = ('--no-save', '--no-restore', '--no-site-file', '--no-environ')
|
||||||
|
entry = shlex.split(hook.entry)
|
||||||
|
_entry_validate(entry)
|
||||||
|
|
||||||
|
return (
|
||||||
|
*entry[:1], *opts,
|
||||||
|
*_prefix_if_file_entry(entry, hook.prefix),
|
||||||
|
*hook.args,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def install_environment(
|
||||||
|
prefix: Prefix,
|
||||||
|
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)
|
||||||
|
path_desc_source = prefix.path('DESCRIPTION')
|
||||||
|
if os.path.exists(path_desc_source):
|
||||||
|
shutil.copy(path_desc_source, env_dir)
|
||||||
|
shutil.copy(prefix.path('renv.lock'), env_dir)
|
||||||
|
cmd_output_b(
|
||||||
|
'Rscript', '--vanilla', '-e',
|
||||||
|
"""\
|
||||||
|
missing_pkgs <- setdiff(
|
||||||
|
"renv", unname(installed.packages()[, "Package"])
|
||||||
|
)
|
||||||
|
options(
|
||||||
|
repos = c(CRAN = "https://cran.rstudio.com"),
|
||||||
|
renv.consent = TRUE
|
||||||
|
)
|
||||||
|
install.packages(missing_pkgs)
|
||||||
|
renv::activate()
|
||||||
|
renv::restore()
|
||||||
|
activate_statement <- paste0(
|
||||||
|
'renv::activate("', file.path(getwd()), '"); '
|
||||||
|
)
|
||||||
|
writeLines(activate_statement, 'activate.R')
|
||||||
|
is_package <- tryCatch(
|
||||||
|
suppressWarnings(
|
||||||
|
unname(read.dcf('DESCRIPTION')[,'Type'] == "Package")
|
||||||
|
),
|
||||||
|
error = function(...) FALSE
|
||||||
|
)
|
||||||
|
if (is_package) {
|
||||||
|
renv::install(normalizePath('.'))
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
cwd=env_dir,
|
||||||
|
)
|
||||||
|
if additional_dependencies:
|
||||||
|
cmd_output_b(
|
||||||
|
'Rscript', '-e',
|
||||||
|
'renv::install(commandArgs(trailingOnly = TRUE))',
|
||||||
|
*additional_dependencies,
|
||||||
|
cwd=env_dir,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def run_hook(
|
||||||
|
hook: Hook,
|
||||||
|
file_args: Sequence[str],
|
||||||
|
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,
|
||||||
|
)
|
||||||
20
pre_commit/resources/empty_template_renv.lock
Normal file
20
pre_commit/resources/empty_template_renv.lock
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"R": {
|
||||||
|
"Version": "4.0.3",
|
||||||
|
"Repositories": [
|
||||||
|
{
|
||||||
|
"Name": "CRAN",
|
||||||
|
"URL": "https://cran.rstudio.com"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Packages": {
|
||||||
|
"renv": {
|
||||||
|
"Package": "renv",
|
||||||
|
"Version": "0.12.5",
|
||||||
|
"Source": "Repository",
|
||||||
|
"Repository": "CRAN",
|
||||||
|
"Hash": "5c0cdb37f063c58cdab3c7e9fbb8bd2c"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -189,7 +189,7 @@ class Store:
|
||||||
LOCAL_RESOURCES = (
|
LOCAL_RESOURCES = (
|
||||||
'Cargo.toml', 'main.go', 'go.mod', 'main.rs', '.npmignore',
|
'Cargo.toml', 'main.go', 'go.mod', 'main.rs', '.npmignore',
|
||||||
'package.json', 'pre_commit_dummy_package.gemspec', 'setup.py',
|
'package.json', 'pre_commit_dummy_package.gemspec', 'setup.py',
|
||||||
'environment.yml', 'Makefile.PL',
|
'environment.yml', 'Makefile.PL', 'renv.lock',
|
||||||
)
|
)
|
||||||
|
|
||||||
def make_local(self, deps: Sequence[str]) -> str:
|
def make_local(self, deps: Sequence[str]) -> str:
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
LANGUAGES = [
|
LANGUAGES = [
|
||||||
'conda', 'coursier', 'docker', 'dotnet', 'docker_image', 'fail', 'golang',
|
'conda', 'coursier', 'docker', 'docker_image', 'dotnet', 'fail', 'golang',
|
||||||
'node', 'perl', 'pygrep', 'python', 'ruby', 'rust', 'script', 'swift',
|
'node', 'perl', 'pygrep', 'python', 'r', 'ruby', 'rust', 'script',
|
||||||
'system',
|
'swift', 'system',
|
||||||
]
|
]
|
||||||
FIELDS = [
|
FIELDS = [
|
||||||
'ENVIRONMENT_DIR', 'get_default_version', 'healthy', 'install_environment',
|
'ENVIRONMENT_DIR', 'get_default_version', 'healthy', 'install_environment',
|
||||||
|
|
|
||||||
6
testing/get-r.ps1
Normal file
6
testing/get-r.ps1
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
$dir = $Env:Temp
|
||||||
|
$urlR = "https://cran.r-project.org/bin/windows/base/old/4.0.4/R-4.0.4-win.exe"
|
||||||
|
$outputR = "$dir\R-win.exe"
|
||||||
|
$wcR = New-Object System.Net.WebClient
|
||||||
|
$wcR.DownloadFile($urlR, $outputR)
|
||||||
|
Start-Process -FilePath $outputR -ArgumentList "/S /v/qn"
|
||||||
9
testing/get-r.sh
Executable file
9
testing/get-r.sh
Executable file
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
sudo apt install r-base
|
||||||
|
# create empty folder for user library.
|
||||||
|
# necessary for non-root users who have
|
||||||
|
# never installed an R package before.
|
||||||
|
# Alternatively, we require the renv
|
||||||
|
# package to be installed already, then we can
|
||||||
|
# omit that.
|
||||||
|
Rscript -e 'dir.create(Sys.getenv("R_LIBS_USER"), recursive = TRUE)'
|
||||||
48
testing/resources/r_hooks_repo/.pre-commit-hooks.yaml
Normal file
48
testing/resources/r_hooks_repo/.pre-commit-hooks.yaml
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
# parsing file
|
||||||
|
- id: parse-file-no-opts-no-args
|
||||||
|
name: Say hi
|
||||||
|
entry: Rscript parse-file-no-opts-no-args.R
|
||||||
|
language: r
|
||||||
|
types: [r]
|
||||||
|
- id: parse-file-no-opts-args
|
||||||
|
name: Say hi
|
||||||
|
entry: Rscript parse-file-no-opts-args.R
|
||||||
|
args: [--no-cache]
|
||||||
|
language: r
|
||||||
|
types: [r]
|
||||||
|
## parsing expr
|
||||||
|
- id: parse-expr-no-opts-no-args-1
|
||||||
|
name: Say hi
|
||||||
|
entry: Rscript -e '1+1'
|
||||||
|
language: r
|
||||||
|
types: [r]
|
||||||
|
- id: parse-expr-args-in-entry-2
|
||||||
|
name: Say hi
|
||||||
|
entry: Rscript -e '1+1' -e '3' --no-cache3
|
||||||
|
language: r
|
||||||
|
types: [r]
|
||||||
|
# real world
|
||||||
|
- id: hello-world
|
||||||
|
name: Say hi
|
||||||
|
entry: Rscript hello-world.R
|
||||||
|
args: [blibla]
|
||||||
|
language: r
|
||||||
|
types: [r]
|
||||||
|
- id: hello-world-inline
|
||||||
|
name: Say hi
|
||||||
|
entry: |
|
||||||
|
Rscript -e
|
||||||
|
'stopifnot(
|
||||||
|
packageVersion("rprojroot") == "1.0",
|
||||||
|
packageVersion("gli.clu") == "0.0.0.9000"
|
||||||
|
)
|
||||||
|
cat(commandArgs(trailingOnly = TRUE), "from R!\n", sep = ", ")
|
||||||
|
'
|
||||||
|
args: ['Hi-there']
|
||||||
|
language: r
|
||||||
|
types: [r]
|
||||||
|
- id: additional-deps
|
||||||
|
name: Check additional deps
|
||||||
|
entry: Rscript additional-deps.R
|
||||||
|
language: r
|
||||||
|
types: [r]
|
||||||
19
testing/resources/r_hooks_repo/DESCRIPTION
Normal file
19
testing/resources/r_hooks_repo/DESCRIPTION
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
Package: gli.clu
|
||||||
|
Title: What the Package Does (One Line, Title Case)
|
||||||
|
Type: Package
|
||||||
|
Version: 0.0.0.9000
|
||||||
|
Authors@R:
|
||||||
|
person(given = "First",
|
||||||
|
family = "Last",
|
||||||
|
role = c("aut", "cre"),
|
||||||
|
email = "first.last@example.com",
|
||||||
|
comment = c(ORCID = "YOUR-ORCID-ID"))
|
||||||
|
Description: What the package does (one paragraph).
|
||||||
|
License: `use_mit_license()`, `use_gpl3_license()` or friends to
|
||||||
|
pick a license
|
||||||
|
Encoding: UTF-8
|
||||||
|
LazyData: true
|
||||||
|
Roxygen: list(markdown = TRUE)
|
||||||
|
RoxygenNote: 7.1.1
|
||||||
|
Imports:
|
||||||
|
rprojroot
|
||||||
2
testing/resources/r_hooks_repo/additional-deps.R
Executable file
2
testing/resources/r_hooks_repo/additional-deps.R
Executable file
|
|
@ -0,0 +1,2 @@
|
||||||
|
suppressPackageStartupMessages(library("cachem"))
|
||||||
|
cat("OK\n")
|
||||||
5
testing/resources/r_hooks_repo/hello-world.R
Executable file
5
testing/resources/r_hooks_repo/hello-world.R
Executable file
|
|
@ -0,0 +1,5 @@
|
||||||
|
stopifnot(
|
||||||
|
packageVersion('rprojroot') == '1.0',
|
||||||
|
packageVersion('gli.clu') == '0.0.0.9000'
|
||||||
|
)
|
||||||
|
cat("Hello, World, from R!\n")
|
||||||
27
testing/resources/r_hooks_repo/renv.lock
Normal file
27
testing/resources/r_hooks_repo/renv.lock
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"R": {
|
||||||
|
"Version": "4.0.3",
|
||||||
|
"Repositories": [
|
||||||
|
{
|
||||||
|
"Name": "CRAN",
|
||||||
|
"URL": "https://cloud.r-project.org"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Packages": {
|
||||||
|
"renv": {
|
||||||
|
"Package": "renv",
|
||||||
|
"Version": "0.12.5",
|
||||||
|
"Source": "Repository",
|
||||||
|
"Repository": "CRAN",
|
||||||
|
"Hash": "5c0cdb37f063c58cdab3c7e9fbb8bd2c"
|
||||||
|
},
|
||||||
|
"rprojroot": {
|
||||||
|
"Package": "rprojroot",
|
||||||
|
"Version": "1.0",
|
||||||
|
"Source": "Repository",
|
||||||
|
"Repository": "CRAN",
|
||||||
|
"Hash": "86704667fe0860e4fec35afdfec137f3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
104
tests/languages/r_test.py
Normal file
104
tests/languages/r_test.py
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from pre_commit.languages import r
|
||||||
|
from testing.fixtures import make_config_from_repo
|
||||||
|
from testing.fixtures import make_repo
|
||||||
|
from tests.repository_test import _get_hook_no_install
|
||||||
|
|
||||||
|
|
||||||
|
def _test_r_parsing(
|
||||||
|
tempdir_factory,
|
||||||
|
store,
|
||||||
|
hook_id,
|
||||||
|
expected_hook_expr={},
|
||||||
|
expected_args={},
|
||||||
|
):
|
||||||
|
repo_path = 'r_hooks_repo'
|
||||||
|
path = make_repo(tempdir_factory, repo_path)
|
||||||
|
config = make_config_from_repo(path)
|
||||||
|
hook = _get_hook_no_install(config, store, hook_id)
|
||||||
|
ret = r._cmd_from_hook(hook)
|
||||||
|
expected_cmd = 'Rscript'
|
||||||
|
expected_opts = (
|
||||||
|
'--no-save', '--no-restore', '--no-site-file', '--no-environ',
|
||||||
|
)
|
||||||
|
expected_path = os.path.join(
|
||||||
|
hook.prefix.prefix_dir, '.'.join([hook_id, 'R']),
|
||||||
|
)
|
||||||
|
expected = (
|
||||||
|
expected_cmd,
|
||||||
|
*expected_opts,
|
||||||
|
*(expected_hook_expr or (expected_path,)),
|
||||||
|
*expected_args,
|
||||||
|
)
|
||||||
|
assert ret == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_r_parsing_file_no_opts_no_args(tempdir_factory, store):
|
||||||
|
hook_id = 'parse-file-no-opts-no-args'
|
||||||
|
_test_r_parsing(tempdir_factory, store, hook_id)
|
||||||
|
|
||||||
|
|
||||||
|
def test_r_parsing_file_opts_no_args(tempdir_factory, store):
|
||||||
|
with pytest.raises(ValueError) as excinfo:
|
||||||
|
r._entry_validate(['Rscript', '--no-init', '/path/to/file'])
|
||||||
|
|
||||||
|
msg = excinfo.value.args
|
||||||
|
assert msg == (
|
||||||
|
'The only valid syntax is `Rscript -e {expr}`',
|
||||||
|
'or `Rscript path/to/hook/script`',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_r_parsing_file_no_opts_args(tempdir_factory, store):
|
||||||
|
hook_id = 'parse-file-no-opts-args'
|
||||||
|
expected_args = ['--no-cache']
|
||||||
|
_test_r_parsing(
|
||||||
|
tempdir_factory, store, hook_id, expected_args=expected_args,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_r_parsing_expr_no_opts_no_args1(tempdir_factory, store):
|
||||||
|
hook_id = 'parse-expr-no-opts-no-args-1'
|
||||||
|
_test_r_parsing(
|
||||||
|
tempdir_factory, store, hook_id, expected_hook_expr=('-e', '1+1'),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_r_parsing_expr_no_opts_no_args2(tempdir_factory, store):
|
||||||
|
with pytest.raises(ValueError) as execinfo:
|
||||||
|
r._entry_validate(['Rscript', '-e', '1+1', '-e', 'letters'])
|
||||||
|
msg = execinfo.value.args
|
||||||
|
assert msg == ('You can supply at most one expression.',)
|
||||||
|
|
||||||
|
|
||||||
|
def test_r_parsing_expr_opts_no_args2(tempdir_factory, store):
|
||||||
|
with pytest.raises(ValueError) as execinfo:
|
||||||
|
r._entry_validate(
|
||||||
|
[
|
||||||
|
'Rscript', '--vanilla', '-e', '1+1', '-e', 'letters',
|
||||||
|
],
|
||||||
|
)
|
||||||
|
msg = execinfo.value.args
|
||||||
|
assert msg == (
|
||||||
|
'The only valid syntax is `Rscript -e {expr}`',
|
||||||
|
'or `Rscript path/to/hook/script`',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_r_parsing_expr_args_in_entry2(tempdir_factory, store):
|
||||||
|
with pytest.raises(ValueError) as execinfo:
|
||||||
|
r._entry_validate(['Rscript', '-e', 'expr1', '--another-arg'])
|
||||||
|
|
||||||
|
msg = execinfo.value.args
|
||||||
|
assert msg == ('You can supply at most one expression.',)
|
||||||
|
|
||||||
|
|
||||||
|
def test_r_parsing_expr_non_Rscirpt(tempdir_factory, store):
|
||||||
|
with pytest.raises(ValueError) as execinfo:
|
||||||
|
r._entry_validate(['AnotherScript', '-e', '{{}}'])
|
||||||
|
|
||||||
|
msg = execinfo.value.args
|
||||||
|
assert msg == ('entry must start with `Rscript`.',)
|
||||||
|
|
@ -279,6 +279,54 @@ def test_node_hook_with_npm_userconfig_set(tempdir_factory, store, tmpdir):
|
||||||
test_run_a_node_hook(tempdir_factory, store)
|
test_run_a_node_hook(tempdir_factory, store)
|
||||||
|
|
||||||
|
|
||||||
|
def test_r_hook(tempdir_factory, store):
|
||||||
|
_test_hook_repo(
|
||||||
|
tempdir_factory, store, 'r_hooks_repo',
|
||||||
|
'hello-world', [os.devnull],
|
||||||
|
b'Hello, World, from R!\n',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_r_inline_hook(tempdir_factory, store):
|
||||||
|
_test_hook_repo(
|
||||||
|
tempdir_factory, store, 'r_hooks_repo',
|
||||||
|
'hello-world-inline', ['some-file'],
|
||||||
|
b'Hi-there, some-file, from R!\n',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_r_with_additional_dependencies_hook(tempdir_factory, store):
|
||||||
|
_test_hook_repo(
|
||||||
|
tempdir_factory, store, 'r_hooks_repo',
|
||||||
|
'additional-deps', [os.devnull],
|
||||||
|
b'OK\n',
|
||||||
|
config_kwargs={
|
||||||
|
'hooks': [{
|
||||||
|
'id': 'additional-deps',
|
||||||
|
'additional_dependencies': ['cachem@1.0.4'],
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_r_local_with_additional_dependencies_hook(store):
|
||||||
|
config = {
|
||||||
|
'repo': 'local',
|
||||||
|
'hooks': [{
|
||||||
|
'id': 'local-r',
|
||||||
|
'name': 'local-r',
|
||||||
|
'entry': 'Rscript -e',
|
||||||
|
'language': 'r',
|
||||||
|
'args': ['if (packageVersion("R6") == "2.1.3") cat("OK\n")'],
|
||||||
|
'additional_dependencies': ['R6@2.1.3'],
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
hook = _get_hook(config, store, 'local-r')
|
||||||
|
ret, out = _hook_run(hook, (), color=False)
|
||||||
|
assert ret == 0
|
||||||
|
assert _norm_out(out) == b'OK\n'
|
||||||
|
|
||||||
|
|
||||||
def test_run_a_ruby_hook(tempdir_factory, store):
|
def test_run_a_ruby_hook(tempdir_factory, store):
|
||||||
_test_hook_repo(
|
_test_hook_repo(
|
||||||
tempdir_factory, store, 'ruby_hooks_repo',
|
tempdir_factory, store, 'ruby_hooks_repo',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue