Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1799 from lorenzwalthert/renv
Support for R / renv as a language
- Loading branch information
Showing
15 changed files
with
443 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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)' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
suppressPackageStartupMessages(library("cachem")) | ||
cat("OK\n") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
stopifnot( | ||
packageVersion('rprojroot') == '1.0', | ||
packageVersion('gli.clu') == '0.0.0.9000' | ||
) | ||
cat("Hello, World, from R!\n") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" | ||
} | ||
} | ||
} |
Oops, something went wrong.