Merging upstream version 3.0.2.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
962b6a60c2
commit
3904671ae3
107 changed files with 1775 additions and 2323 deletions
|
@ -1,10 +1,9 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import Callable
|
||||
from typing import NamedTuple
|
||||
from typing import ContextManager
|
||||
from typing import Protocol
|
||||
from typing import Sequence
|
||||
|
||||
from pre_commit.hook import Hook
|
||||
from pre_commit.languages import conda
|
||||
from pre_commit.languages import coursier
|
||||
from pre_commit.languages import dart
|
||||
|
@ -27,44 +26,74 @@ from pre_commit.languages import system
|
|||
from pre_commit.prefix import Prefix
|
||||
|
||||
|
||||
class Language(NamedTuple):
|
||||
name: str
|
||||
class Language(Protocol):
|
||||
# Use `None` for no installation / environment
|
||||
ENVIRONMENT_DIR: str | None
|
||||
@property
|
||||
def ENVIRONMENT_DIR(self) -> str | None: ...
|
||||
# return a value to replace `'default` for `language_version`
|
||||
get_default_version: Callable[[], str]
|
||||
def get_default_version(self) -> str: ...
|
||||
|
||||
# return whether the environment is healthy (or should be rebuilt)
|
||||
health_check: Callable[[Prefix, str], str | None]
|
||||
def health_check(
|
||||
self,
|
||||
prefix: Prefix,
|
||||
language_version: str,
|
||||
) -> str | None:
|
||||
...
|
||||
|
||||
# install a repository for the given language and language_version
|
||||
install_environment: Callable[[Prefix, str, Sequence[str]], None]
|
||||
def install_environment(
|
||||
self,
|
||||
prefix: Prefix,
|
||||
version: str,
|
||||
additional_dependencies: Sequence[str],
|
||||
) -> None:
|
||||
...
|
||||
|
||||
# modify the environment for hook execution
|
||||
def in_env(
|
||||
self,
|
||||
prefix: Prefix,
|
||||
version: str,
|
||||
) -> ContextManager[None]:
|
||||
...
|
||||
|
||||
# execute a hook and return the exit code and output
|
||||
run_hook: Callable[[Hook, Sequence[str], bool], tuple[int, bytes]]
|
||||
def run_hook(
|
||||
self,
|
||||
prefix: Prefix,
|
||||
entry: str,
|
||||
args: Sequence[str],
|
||||
file_args: Sequence[str],
|
||||
*,
|
||||
is_local: bool,
|
||||
require_serial: bool,
|
||||
color: bool,
|
||||
) -> tuple[int, bytes]:
|
||||
...
|
||||
|
||||
|
||||
# TODO: back to modules + Protocol: https://github.com/python/mypy/issues/5018
|
||||
languages = {
|
||||
# BEGIN GENERATED (testing/gen-languages-all)
|
||||
'conda': Language(name='conda', ENVIRONMENT_DIR=conda.ENVIRONMENT_DIR, get_default_version=conda.get_default_version, health_check=conda.health_check, install_environment=conda.install_environment, run_hook=conda.run_hook), # noqa: E501
|
||||
'coursier': Language(name='coursier', ENVIRONMENT_DIR=coursier.ENVIRONMENT_DIR, get_default_version=coursier.get_default_version, health_check=coursier.health_check, install_environment=coursier.install_environment, run_hook=coursier.run_hook), # noqa: E501
|
||||
'dart': Language(name='dart', ENVIRONMENT_DIR=dart.ENVIRONMENT_DIR, get_default_version=dart.get_default_version, health_check=dart.health_check, install_environment=dart.install_environment, run_hook=dart.run_hook), # noqa: E501
|
||||
'docker': Language(name='docker', ENVIRONMENT_DIR=docker.ENVIRONMENT_DIR, get_default_version=docker.get_default_version, health_check=docker.health_check, install_environment=docker.install_environment, run_hook=docker.run_hook), # noqa: E501
|
||||
'docker_image': Language(name='docker_image', ENVIRONMENT_DIR=docker_image.ENVIRONMENT_DIR, get_default_version=docker_image.get_default_version, health_check=docker_image.health_check, install_environment=docker_image.install_environment, run_hook=docker_image.run_hook), # noqa: E501
|
||||
'dotnet': Language(name='dotnet', ENVIRONMENT_DIR=dotnet.ENVIRONMENT_DIR, get_default_version=dotnet.get_default_version, health_check=dotnet.health_check, install_environment=dotnet.install_environment, run_hook=dotnet.run_hook), # noqa: E501
|
||||
'fail': Language(name='fail', ENVIRONMENT_DIR=fail.ENVIRONMENT_DIR, get_default_version=fail.get_default_version, health_check=fail.health_check, install_environment=fail.install_environment, run_hook=fail.run_hook), # noqa: E501
|
||||
'golang': Language(name='golang', ENVIRONMENT_DIR=golang.ENVIRONMENT_DIR, get_default_version=golang.get_default_version, health_check=golang.health_check, install_environment=golang.install_environment, run_hook=golang.run_hook), # noqa: E501
|
||||
'lua': Language(name='lua', ENVIRONMENT_DIR=lua.ENVIRONMENT_DIR, get_default_version=lua.get_default_version, health_check=lua.health_check, install_environment=lua.install_environment, run_hook=lua.run_hook), # noqa: E501
|
||||
'node': Language(name='node', ENVIRONMENT_DIR=node.ENVIRONMENT_DIR, get_default_version=node.get_default_version, health_check=node.health_check, install_environment=node.install_environment, run_hook=node.run_hook), # noqa: E501
|
||||
'perl': Language(name='perl', ENVIRONMENT_DIR=perl.ENVIRONMENT_DIR, get_default_version=perl.get_default_version, health_check=perl.health_check, 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, health_check=pygrep.health_check, 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, health_check=python.health_check, 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, health_check=r.health_check, 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, health_check=ruby.health_check, 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, health_check=rust.health_check, 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, health_check=script.health_check, install_environment=script.install_environment, run_hook=script.run_hook), # noqa: E501
|
||||
'swift': Language(name='swift', ENVIRONMENT_DIR=swift.ENVIRONMENT_DIR, get_default_version=swift.get_default_version, health_check=swift.health_check, install_environment=swift.install_environment, run_hook=swift.run_hook), # noqa: E501
|
||||
'system': Language(name='system', ENVIRONMENT_DIR=system.ENVIRONMENT_DIR, get_default_version=system.get_default_version, health_check=system.health_check, install_environment=system.install_environment, run_hook=system.run_hook), # noqa: E501
|
||||
# END GENERATED
|
||||
languages: dict[str, Language] = {
|
||||
'conda': conda,
|
||||
'coursier': coursier,
|
||||
'dart': dart,
|
||||
'docker': docker,
|
||||
'docker_image': docker_image,
|
||||
'dotnet': dotnet,
|
||||
'fail': fail,
|
||||
'golang': golang,
|
||||
'lua': lua,
|
||||
'node': node,
|
||||
'perl': perl,
|
||||
'pygrep': pygrep,
|
||||
'python': python,
|
||||
'r': r,
|
||||
'ruby': ruby,
|
||||
'rust': rust,
|
||||
'script': script,
|
||||
'swift': swift,
|
||||
'system': system,
|
||||
# TODO: fully deprecate `python_venv`
|
||||
'python_venv': python,
|
||||
}
|
||||
# TODO: fully deprecate `python_venv`
|
||||
languages['python_venv'] = languages['python']
|
||||
all_languages = sorted(languages)
|
||||
|
|
|
@ -10,15 +10,14 @@ from pre_commit.envcontext import PatchesT
|
|||
from pre_commit.envcontext import SubstitutionT
|
||||
from pre_commit.envcontext import UNSET
|
||||
from pre_commit.envcontext import Var
|
||||
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 = 'conda'
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
health_check = helpers.basic_health_check
|
||||
run_hook = helpers.basic_run_hook
|
||||
|
||||
|
||||
def get_env_patch(env: str) -> PatchesT:
|
||||
|
@ -41,12 +40,8 @@ def get_env_patch(env: str) -> PatchesT:
|
|||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_env(
|
||||
prefix: Prefix,
|
||||
language_version: str,
|
||||
) -> Generator[None, None, None]:
|
||||
directory = helpers.environment_dir(ENVIRONMENT_DIR, language_version)
|
||||
envdir = prefix.path(directory)
|
||||
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
|
||||
|
||||
|
@ -66,31 +61,16 @@ def install_environment(
|
|||
additional_dependencies: Sequence[str],
|
||||
) -> None:
|
||||
helpers.assert_version_default('conda', version)
|
||||
directory = helpers.environment_dir(ENVIRONMENT_DIR, version)
|
||||
|
||||
conda_exe = _conda_exe()
|
||||
|
||||
env_dir = prefix.path(directory)
|
||||
with clean_path_on_failure(env_dir):
|
||||
env_dir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||
cmd_output_b(
|
||||
conda_exe, 'env', 'create', '-p', env_dir, '--file',
|
||||
'environment.yml', cwd=prefix.prefix_dir,
|
||||
)
|
||||
if additional_dependencies:
|
||||
cmd_output_b(
|
||||
conda_exe, 'env', 'create', '-p', env_dir, '--file',
|
||||
'environment.yml', cwd=prefix.prefix_dir,
|
||||
conda_exe, 'install', '-p', env_dir, *additional_dependencies,
|
||||
cwd=prefix.prefix_dir,
|
||||
)
|
||||
if additional_dependencies:
|
||||
cmd_output_b(
|
||||
conda_exe, 'install', '-p', env_dir, *additional_dependencies,
|
||||
cwd=prefix.prefix_dir,
|
||||
)
|
||||
|
||||
|
||||
def run_hook(
|
||||
hook: Hook,
|
||||
file_args: Sequence[str],
|
||||
color: bool,
|
||||
) -> tuple[int, bytes]:
|
||||
# TODO: Some rare commands need to be run using `conda run` but mostly we
|
||||
# can run them without which is much quicker and produces a better
|
||||
# output.
|
||||
# cmd = ('conda', 'run', '-p', env_dir) + hook.cmd
|
||||
with in_env(hook.prefix, hook.language_version):
|
||||
return helpers.run_xargs(hook, hook.cmd, file_args, color=color)
|
||||
|
|
|
@ -1,81 +1,76 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
import os
|
||||
import os.path
|
||||
from typing import Generator
|
||||
from typing import Sequence
|
||||
|
||||
from pre_commit.envcontext import envcontext
|
||||
from pre_commit.envcontext import PatchesT
|
||||
from pre_commit.envcontext import Var
|
||||
from pre_commit.hook import Hook
|
||||
from pre_commit.errors import FatalError
|
||||
from pre_commit.languages import helpers
|
||||
from pre_commit.parse_shebang import find_executable
|
||||
from pre_commit.prefix import Prefix
|
||||
from pre_commit.util import clean_path_on_failure
|
||||
|
||||
ENVIRONMENT_DIR = 'coursier'
|
||||
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
health_check = helpers.basic_health_check
|
||||
run_hook = helpers.basic_run_hook
|
||||
|
||||
|
||||
def install_environment(
|
||||
prefix: Prefix,
|
||||
version: str,
|
||||
additional_dependencies: Sequence[str],
|
||||
) -> None: # pragma: win32 no cover
|
||||
) -> None:
|
||||
helpers.assert_version_default('coursier', version)
|
||||
helpers.assert_no_additional_deps('coursier', additional_dependencies)
|
||||
|
||||
# Support both possible executable names (either "cs" or "coursier")
|
||||
executable = find_executable('cs') or find_executable('coursier')
|
||||
if executable is None:
|
||||
cs = find_executable('cs') or find_executable('coursier')
|
||||
if cs is None:
|
||||
raise AssertionError(
|
||||
'pre-commit requires system-installed "cs" or "coursier" '
|
||||
'executables in the application search path',
|
||||
)
|
||||
|
||||
envdir = prefix.path(helpers.environment_dir(ENVIRONMENT_DIR, version))
|
||||
channel = prefix.path('.pre-commit-channel')
|
||||
with clean_path_on_failure(envdir):
|
||||
for app_descriptor in os.listdir(channel):
|
||||
_, app_file = os.path.split(app_descriptor)
|
||||
app, _ = os.path.splitext(app_file)
|
||||
helpers.run_setup_cmd(
|
||||
prefix,
|
||||
(
|
||||
executable,
|
||||
'install',
|
||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||
|
||||
def _install(*opts: str) -> None:
|
||||
assert cs is not None
|
||||
helpers.run_setup_cmd(prefix, (cs, 'fetch', *opts))
|
||||
helpers.run_setup_cmd(prefix, (cs, 'install', '--dir', envdir, *opts))
|
||||
|
||||
with in_env(prefix, version):
|
||||
channel = prefix.path('.pre-commit-channel')
|
||||
if os.path.isdir(channel):
|
||||
for app_descriptor in os.listdir(channel):
|
||||
_, app_file = os.path.split(app_descriptor)
|
||||
app, _ = os.path.splitext(app_file)
|
||||
_install(
|
||||
'--default-channels=false',
|
||||
f'--channel={channel}',
|
||||
'--channel', channel,
|
||||
app,
|
||||
f'--dir={envdir}',
|
||||
),
|
||||
)
|
||||
elif not additional_dependencies:
|
||||
raise FatalError(
|
||||
'expected .pre-commit-channel dir or additional_dependencies',
|
||||
)
|
||||
|
||||
if additional_dependencies:
|
||||
_install(*additional_dependencies)
|
||||
|
||||
def get_env_patch(target_dir: str) -> PatchesT: # pragma: win32 no cover
|
||||
|
||||
def get_env_patch(target_dir: str) -> PatchesT:
|
||||
return (
|
||||
('PATH', (target_dir, os.pathsep, Var('PATH'))),
|
||||
('COURSIER_CACHE', os.path.join(target_dir, '.cs-cache')),
|
||||
)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_env(
|
||||
prefix: Prefix,
|
||||
) -> Generator[None, None, None]: # pragma: win32 no cover
|
||||
target_dir = prefix.path(
|
||||
helpers.environment_dir(ENVIRONMENT_DIR, get_default_version()),
|
||||
)
|
||||
with envcontext(get_env_patch(target_dir)):
|
||||
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 run_hook(
|
||||
hook: Hook,
|
||||
file_args: Sequence[str],
|
||||
color: bool,
|
||||
) -> tuple[int, bytes]: # pragma: win32 no cover
|
||||
with in_env(hook.prefix):
|
||||
return helpers.run_xargs(hook, hook.cmd, file_args, color=color)
|
||||
|
|
|
@ -7,21 +7,19 @@ import tempfile
|
|||
from typing import Generator
|
||||
from typing import Sequence
|
||||
|
||||
import pre_commit.constants as C
|
||||
from pre_commit.envcontext import envcontext
|
||||
from pre_commit.envcontext import PatchesT
|
||||
from pre_commit.envcontext import Var
|
||||
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 win_exe
|
||||
from pre_commit.util import yaml_load
|
||||
from pre_commit.yaml import yaml_load
|
||||
|
||||
ENVIRONMENT_DIR = 'dartenv'
|
||||
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
health_check = helpers.basic_health_check
|
||||
run_hook = helpers.basic_run_hook
|
||||
|
||||
|
||||
def get_env_patch(venv: str) -> PatchesT:
|
||||
|
@ -31,9 +29,8 @@ def get_env_patch(venv: str) -> PatchesT:
|
|||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_env(prefix: Prefix) -> Generator[None, None, None]:
|
||||
directory = helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT)
|
||||
envdir = prefix.path(directory)
|
||||
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
|
||||
|
||||
|
@ -45,7 +42,7 @@ def install_environment(
|
|||
) -> None:
|
||||
helpers.assert_version_default('dart', version)
|
||||
|
||||
envdir = prefix.path(helpers.environment_dir(ENVIRONMENT_DIR, version))
|
||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||
bin_dir = os.path.join(envdir, 'bin')
|
||||
|
||||
def _install_dir(prefix_p: Prefix, pub_cache: str) -> None:
|
||||
|
@ -67,44 +64,34 @@ def install_environment(
|
|||
env=dart_env,
|
||||
)
|
||||
|
||||
with clean_path_on_failure(envdir):
|
||||
os.makedirs(bin_dir)
|
||||
os.makedirs(bin_dir)
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
_install_dir(prefix, tmp)
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
_install_dir(prefix, tmp)
|
||||
|
||||
for dep_s in additional_dependencies:
|
||||
with tempfile.TemporaryDirectory() as dep_tmp:
|
||||
dep, _, version = dep_s.partition(':')
|
||||
if version:
|
||||
dep_cmd: tuple[str, ...] = (dep, '--version', version)
|
||||
else:
|
||||
dep_cmd = (dep,)
|
||||
for dep_s in additional_dependencies:
|
||||
with tempfile.TemporaryDirectory() as dep_tmp:
|
||||
dep, _, version = dep_s.partition(':')
|
||||
if version:
|
||||
dep_cmd: tuple[str, ...] = (dep, '--version', version)
|
||||
else:
|
||||
dep_cmd = (dep,)
|
||||
|
||||
helpers.run_setup_cmd(
|
||||
prefix,
|
||||
('dart', 'pub', 'cache', 'add', *dep_cmd),
|
||||
env={**os.environ, 'PUB_CACHE': dep_tmp},
|
||||
helpers.run_setup_cmd(
|
||||
prefix,
|
||||
('dart', 'pub', 'cache', 'add', *dep_cmd),
|
||||
env={**os.environ, 'PUB_CACHE': dep_tmp},
|
||||
)
|
||||
|
||||
# try and find the 'pubspec.yaml' that just got added
|
||||
for root, _, filenames in os.walk(dep_tmp):
|
||||
if 'pubspec.yaml' in filenames:
|
||||
with tempfile.TemporaryDirectory() as copied:
|
||||
pkg = os.path.join(copied, 'pkg')
|
||||
shutil.copytree(root, pkg)
|
||||
_install_dir(Prefix(pkg), dep_tmp)
|
||||
break
|
||||
else:
|
||||
raise AssertionError(
|
||||
f'could not find pubspec.yaml for {dep_s}',
|
||||
)
|
||||
|
||||
# try and find the 'pubspec.yaml' that just got added
|
||||
for root, _, filenames in os.walk(dep_tmp):
|
||||
if 'pubspec.yaml' in filenames:
|
||||
with tempfile.TemporaryDirectory() as copied:
|
||||
pkg = os.path.join(copied, 'pkg')
|
||||
shutil.copytree(root, pkg)
|
||||
_install_dir(Prefix(pkg), dep_tmp)
|
||||
break
|
||||
else:
|
||||
raise AssertionError(
|
||||
f'could not find pubspec.yaml for {dep_s}',
|
||||
)
|
||||
|
||||
|
||||
def run_hook(
|
||||
hook: Hook,
|
||||
file_args: Sequence[str],
|
||||
color: bool,
|
||||
) -> tuple[int, bytes]:
|
||||
with in_env(hook.prefix):
|
||||
return helpers.run_xargs(hook, hook.cmd, file_args, color=color)
|
||||
|
|
|
@ -5,18 +5,16 @@ import json
|
|||
import os
|
||||
from typing import Sequence
|
||||
|
||||
import pre_commit.constants as C
|
||||
from pre_commit.hook import Hook
|
||||
from pre_commit.languages import helpers
|
||||
from pre_commit.prefix import Prefix
|
||||
from pre_commit.util import CalledProcessError
|
||||
from pre_commit.util import clean_path_on_failure
|
||||
from pre_commit.util import cmd_output_b
|
||||
|
||||
ENVIRONMENT_DIR = 'docker'
|
||||
PRE_COMMIT_LABEL = 'PRE_COMMIT'
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
health_check = helpers.basic_health_check
|
||||
in_env = helpers.no_env # no special environment for docker
|
||||
|
||||
|
||||
def _is_in_docker() -> bool:
|
||||
|
@ -95,15 +93,12 @@ def install_environment(
|
|||
helpers.assert_version_default('docker', version)
|
||||
helpers.assert_no_additional_deps('docker', additional_dependencies)
|
||||
|
||||
directory = prefix.path(
|
||||
helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT),
|
||||
)
|
||||
directory = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||
|
||||
# Docker doesn't really have relevant disk environment, but pre-commit
|
||||
# still needs to cleanup its state files on failure
|
||||
with clean_path_on_failure(directory):
|
||||
build_docker_image(prefix, pull=True)
|
||||
os.mkdir(directory)
|
||||
build_docker_image(prefix, pull=True)
|
||||
os.mkdir(directory)
|
||||
|
||||
|
||||
def get_docker_user() -> tuple[str, ...]: # pragma: win32 no cover
|
||||
|
@ -127,16 +122,26 @@ def docker_cmd() -> tuple[str, ...]: # pragma: win32 no cover
|
|||
|
||||
|
||||
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]: # pragma: win32 no cover
|
||||
# Rebuild the docker image in case it has gone missing, as many people do
|
||||
# automated cleanup of docker images.
|
||||
build_docker_image(hook.prefix, pull=False)
|
||||
build_docker_image(prefix, pull=False)
|
||||
|
||||
entry_exe, *cmd_rest = hook.cmd
|
||||
entry_exe, *cmd_rest = helpers.hook_cmd(entry, args)
|
||||
|
||||
entry_tag = ('--entrypoint', entry_exe, docker_tag(hook.prefix))
|
||||
entry_tag = ('--entrypoint', entry_exe, docker_tag(prefix))
|
||||
cmd = (*docker_cmd(), *entry_tag, *cmd_rest)
|
||||
return helpers.run_xargs(hook, cmd, file_args, color=color)
|
||||
return helpers.run_xargs(
|
||||
cmd,
|
||||
file_args,
|
||||
require_serial=require_serial,
|
||||
color=color,
|
||||
)
|
||||
|
|
|
@ -2,20 +2,31 @@ from __future__ import annotations
|
|||
|
||||
from typing import Sequence
|
||||
|
||||
from pre_commit.hook import Hook
|
||||
from pre_commit.languages import helpers
|
||||
from pre_commit.languages.docker import docker_cmd
|
||||
from pre_commit.prefix import Prefix
|
||||
|
||||
ENVIRONMENT_DIR = None
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
health_check = helpers.basic_health_check
|
||||
install_environment = helpers.no_install
|
||||
in_env = helpers.no_env
|
||||
|
||||
|
||||
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]: # pragma: win32 no cover
|
||||
cmd = docker_cmd() + hook.cmd
|
||||
return helpers.run_xargs(hook, cmd, file_args, color=color)
|
||||
cmd = docker_cmd() + helpers.hook_cmd(entry, args)
|
||||
return helpers.run_xargs(
|
||||
cmd,
|
||||
file_args,
|
||||
require_serial=require_serial,
|
||||
color=color,
|
||||
)
|
||||
|
|
|
@ -9,20 +9,18 @@ import zipfile
|
|||
from typing import Generator
|
||||
from typing import Sequence
|
||||
|
||||
import pre_commit.constants as C
|
||||
from pre_commit.envcontext import envcontext
|
||||
from pre_commit.envcontext import PatchesT
|
||||
from pre_commit.envcontext import Var
|
||||
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
|
||||
|
||||
ENVIRONMENT_DIR = 'dotnetenv'
|
||||
BIN_DIR = 'bin'
|
||||
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
health_check = helpers.basic_health_check
|
||||
run_hook = helpers.basic_run_hook
|
||||
|
||||
|
||||
def get_env_patch(venv: str) -> PatchesT:
|
||||
|
@ -32,9 +30,8 @@ def get_env_patch(venv: str) -> PatchesT:
|
|||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_env(prefix: Prefix) -> Generator[None, None, None]:
|
||||
directory = helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT)
|
||||
envdir = prefix.path(directory)
|
||||
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
|
||||
|
||||
|
@ -63,66 +60,56 @@ def install_environment(
|
|||
helpers.assert_version_default('dotnet', version)
|
||||
helpers.assert_no_additional_deps('dotnet', additional_dependencies)
|
||||
|
||||
envdir = prefix.path(helpers.environment_dir(ENVIRONMENT_DIR, version))
|
||||
with clean_path_on_failure(envdir):
|
||||
build_dir = 'pre-commit-build'
|
||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||
build_dir = 'pre-commit-build'
|
||||
|
||||
# Build & pack nupkg file
|
||||
helpers.run_setup_cmd(
|
||||
prefix,
|
||||
(
|
||||
'dotnet', 'pack',
|
||||
'--configuration', 'Release',
|
||||
'--output', build_dir,
|
||||
),
|
||||
)
|
||||
# Build & pack nupkg file
|
||||
helpers.run_setup_cmd(
|
||||
prefix,
|
||||
(
|
||||
'dotnet', 'pack',
|
||||
'--configuration', 'Release',
|
||||
'--output', build_dir,
|
||||
),
|
||||
)
|
||||
|
||||
nupkg_dir = prefix.path(build_dir)
|
||||
nupkgs = [x for x in os.listdir(nupkg_dir) if x.endswith('.nupkg')]
|
||||
nupkg_dir = prefix.path(build_dir)
|
||||
nupkgs = [x for x in os.listdir(nupkg_dir) if x.endswith('.nupkg')]
|
||||
|
||||
if not nupkgs:
|
||||
raise AssertionError('could not find any build outputs to install')
|
||||
if not nupkgs:
|
||||
raise AssertionError('could not find any build outputs to install')
|
||||
|
||||
for nupkg in nupkgs:
|
||||
with zipfile.ZipFile(os.path.join(nupkg_dir, nupkg)) as f:
|
||||
nuspec, = (x for x in f.namelist() if x.endswith('.nuspec'))
|
||||
with f.open(nuspec) as spec:
|
||||
tree = xml.etree.ElementTree.parse(spec)
|
||||
for nupkg in nupkgs:
|
||||
with zipfile.ZipFile(os.path.join(nupkg_dir, nupkg)) as f:
|
||||
nuspec, = (x for x in f.namelist() if x.endswith('.nuspec'))
|
||||
with f.open(nuspec) as spec:
|
||||
tree = xml.etree.ElementTree.parse(spec)
|
||||
|
||||
namespace = re.match(r'{.*}', tree.getroot().tag)
|
||||
if not namespace:
|
||||
raise AssertionError('could not parse namespace from nuspec')
|
||||
namespace = re.match(r'{.*}', tree.getroot().tag)
|
||||
if not namespace:
|
||||
raise AssertionError('could not parse namespace from nuspec')
|
||||
|
||||
tool_id_element = tree.find(f'.//{namespace[0]}id')
|
||||
if tool_id_element is None:
|
||||
raise AssertionError('expected to find an "id" element')
|
||||
tool_id_element = tree.find(f'.//{namespace[0]}id')
|
||||
if tool_id_element is None:
|
||||
raise AssertionError('expected to find an "id" element')
|
||||
|
||||
tool_id = tool_id_element.text
|
||||
if not tool_id:
|
||||
raise AssertionError('"id" element missing tool name')
|
||||
tool_id = tool_id_element.text
|
||||
if not tool_id:
|
||||
raise AssertionError('"id" element missing tool name')
|
||||
|
||||
# Install to bin dir
|
||||
with _nuget_config_no_sources() as nuget_config:
|
||||
helpers.run_setup_cmd(
|
||||
prefix,
|
||||
(
|
||||
'dotnet', 'tool', 'install',
|
||||
'--configfile', nuget_config,
|
||||
'--tool-path', os.path.join(envdir, BIN_DIR),
|
||||
'--add-source', build_dir,
|
||||
tool_id,
|
||||
),
|
||||
)
|
||||
# Install to bin dir
|
||||
with _nuget_config_no_sources() as nuget_config:
|
||||
helpers.run_setup_cmd(
|
||||
prefix,
|
||||
(
|
||||
'dotnet', 'tool', 'install',
|
||||
'--configfile', nuget_config,
|
||||
'--tool-path', os.path.join(envdir, BIN_DIR),
|
||||
'--add-source', build_dir,
|
||||
tool_id,
|
||||
),
|
||||
)
|
||||
|
||||
# Clean the git dir, ignoring the environment dir
|
||||
clean_cmd = ('git', 'clean', '-ffxd', '-e', f'{ENVIRONMENT_DIR}-*')
|
||||
helpers.run_setup_cmd(prefix, clean_cmd)
|
||||
|
||||
|
||||
def run_hook(
|
||||
hook: Hook,
|
||||
file_args: Sequence[str],
|
||||
color: bool,
|
||||
) -> tuple[int, bytes]:
|
||||
with in_env(hook.prefix):
|
||||
return helpers.run_xargs(hook, hook.cmd, file_args, color=color)
|
||||
# Clean the git dir, ignoring the environment dir
|
||||
clean_cmd = ('git', 'clean', '-ffxd', '-e', f'{ENVIRONMENT_DIR}-*')
|
||||
helpers.run_setup_cmd(prefix, clean_cmd)
|
||||
|
|
|
@ -2,20 +2,26 @@ from __future__ import annotations
|
|||
|
||||
from typing import Sequence
|
||||
|
||||
from pre_commit.hook import Hook
|
||||
from pre_commit.languages import helpers
|
||||
from pre_commit.prefix import Prefix
|
||||
|
||||
ENVIRONMENT_DIR = None
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
health_check = helpers.basic_health_check
|
||||
install_environment = helpers.no_install
|
||||
in_env = helpers.no_env
|
||||
|
||||
|
||||
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]:
|
||||
out = f'{hook.entry}\n\n'.encode()
|
||||
out = f'{entry}\n\n'.encode()
|
||||
out += b'\n'.join(f.encode() for f in file_args) + b'\n'
|
||||
return 1, out
|
||||
|
|
|
@ -1,101 +1,159 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
import functools
|
||||
import json
|
||||
import os.path
|
||||
import platform
|
||||
import shutil
|
||||
import sys
|
||||
import tarfile
|
||||
import tempfile
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
import zipfile
|
||||
from typing import ContextManager
|
||||
from typing import Generator
|
||||
from typing import IO
|
||||
from typing import Protocol
|
||||
from typing import Sequence
|
||||
|
||||
import pre_commit.constants as C
|
||||
from pre_commit import git
|
||||
from pre_commit.envcontext import envcontext
|
||||
from pre_commit.envcontext import PatchesT
|
||||
from pre_commit.envcontext import Var
|
||||
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
|
||||
from pre_commit.util import cmd_output_b
|
||||
from pre_commit.util import rmtree
|
||||
|
||||
ENVIRONMENT_DIR = 'golangenv'
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
health_check = helpers.basic_health_check
|
||||
run_hook = helpers.basic_run_hook
|
||||
|
||||
_ARCH_ALIASES = {
|
||||
'x86_64': 'amd64',
|
||||
'i386': '386',
|
||||
'aarch64': 'arm64',
|
||||
'armv8': 'arm64',
|
||||
'armv7l': 'armv6l',
|
||||
}
|
||||
_ARCH = platform.machine().lower()
|
||||
_ARCH = _ARCH_ALIASES.get(_ARCH, _ARCH)
|
||||
|
||||
|
||||
def get_env_patch(venv: str) -> PatchesT:
|
||||
class ExtractAll(Protocol):
|
||||
def extractall(self, path: str) -> None: ...
|
||||
|
||||
|
||||
if sys.platform == 'win32': # pragma: win32 cover
|
||||
_EXT = 'zip'
|
||||
|
||||
def _open_archive(bio: IO[bytes]) -> ContextManager[ExtractAll]:
|
||||
return zipfile.ZipFile(bio)
|
||||
else: # pragma: win32 no cover
|
||||
_EXT = 'tar.gz'
|
||||
|
||||
def _open_archive(bio: IO[bytes]) -> ContextManager[ExtractAll]:
|
||||
return tarfile.open(fileobj=bio)
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=1)
|
||||
def get_default_version() -> str:
|
||||
if helpers.exe_exists('go'):
|
||||
return 'system'
|
||||
else:
|
||||
return C.DEFAULT
|
||||
|
||||
|
||||
def get_env_patch(venv: str, version: str) -> PatchesT:
|
||||
if version == 'system':
|
||||
return (
|
||||
('PATH', (os.path.join(venv, 'bin'), os.pathsep, Var('PATH'))),
|
||||
)
|
||||
|
||||
return (
|
||||
('PATH', (os.path.join(venv, 'bin'), os.pathsep, Var('PATH'))),
|
||||
('GOROOT', os.path.join(venv, '.go')),
|
||||
(
|
||||
'PATH', (
|
||||
os.path.join(venv, 'bin'), os.pathsep,
|
||||
os.path.join(venv, '.go', 'bin'), os.pathsep, Var('PATH'),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@functools.lru_cache
|
||||
def _infer_go_version(version: str) -> str:
|
||||
if version != C.DEFAULT:
|
||||
return version
|
||||
resp = urllib.request.urlopen('https://go.dev/dl/?mode=json')
|
||||
# TODO: 3.9+ .removeprefix('go')
|
||||
return json.load(resp)[0]['version'][2:]
|
||||
|
||||
|
||||
def _get_url(version: str) -> str:
|
||||
os_name = platform.system().lower()
|
||||
version = _infer_go_version(version)
|
||||
return f'https://dl.google.com/go/go{version}.{os_name}-{_ARCH}.{_EXT}'
|
||||
|
||||
|
||||
def _install_go(version: str, dest: str) -> None:
|
||||
try:
|
||||
resp = urllib.request.urlopen(_get_url(version))
|
||||
except urllib.error.HTTPError as e: # pragma: no cover
|
||||
if e.code == 404:
|
||||
raise ValueError(
|
||||
f'Could not find a version matching your system requirements '
|
||||
f'(os={platform.system().lower()}; arch={_ARCH})',
|
||||
) from e
|
||||
else:
|
||||
raise
|
||||
else:
|
||||
with tempfile.TemporaryFile() as f:
|
||||
shutil.copyfileobj(resp, f)
|
||||
f.seek(0)
|
||||
|
||||
with _open_archive(f) as archive:
|
||||
archive.extractall(dest)
|
||||
shutil.move(os.path.join(dest, 'go'), os.path.join(dest, '.go'))
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_env(prefix: Prefix) -> Generator[None, None, None]:
|
||||
envdir = prefix.path(
|
||||
helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT),
|
||||
)
|
||||
with envcontext(get_env_patch(envdir)):
|
||||
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, version)):
|
||||
yield
|
||||
|
||||
|
||||
def guess_go_dir(remote_url: str) -> str:
|
||||
if remote_url.endswith('.git'):
|
||||
remote_url = remote_url[:-1 * len('.git')]
|
||||
looks_like_url = (
|
||||
not remote_url.startswith('file://') and
|
||||
('//' in remote_url or '@' in remote_url)
|
||||
)
|
||||
remote_url = remote_url.replace(':', '/')
|
||||
if looks_like_url:
|
||||
_, _, remote_url = remote_url.rpartition('//')
|
||||
_, _, remote_url = remote_url.rpartition('@')
|
||||
return remote_url
|
||||
else:
|
||||
return 'unknown_src_dir'
|
||||
|
||||
|
||||
def install_environment(
|
||||
prefix: Prefix,
|
||||
version: str,
|
||||
additional_dependencies: Sequence[str],
|
||||
) -> None:
|
||||
helpers.assert_version_default('golang', version)
|
||||
directory = prefix.path(
|
||||
helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT),
|
||||
)
|
||||
env_dir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||
|
||||
with clean_path_on_failure(directory):
|
||||
remote = git.get_remote_url(prefix.prefix_dir)
|
||||
repo_src_dir = os.path.join(directory, 'src', guess_go_dir(remote))
|
||||
if version != 'system':
|
||||
_install_go(version, env_dir)
|
||||
|
||||
# Clone into the goenv we'll create
|
||||
cmd = ('git', 'clone', '--recursive', '.', repo_src_dir)
|
||||
helpers.run_setup_cmd(prefix, cmd)
|
||||
if sys.platform == 'cygwin': # pragma: no cover
|
||||
gopath = cmd_output('cygpath', '-w', env_dir)[1].strip()
|
||||
else:
|
||||
gopath = env_dir
|
||||
|
||||
if sys.platform == 'cygwin': # pragma: no cover
|
||||
_, gopath, _ = cmd_output('cygpath', '-w', directory)
|
||||
gopath = gopath.strip()
|
||||
else:
|
||||
gopath = directory
|
||||
env = dict(os.environ, GOPATH=gopath)
|
||||
env.pop('GOBIN', None)
|
||||
cmd_output_b('go', 'install', './...', cwd=repo_src_dir, env=env)
|
||||
for dependency in additional_dependencies:
|
||||
cmd_output_b(
|
||||
'go', 'install', dependency, cwd=repo_src_dir, env=env,
|
||||
)
|
||||
# Same some disk space, we don't need these after installation
|
||||
rmtree(prefix.path(directory, 'src'))
|
||||
pkgdir = prefix.path(directory, 'pkg')
|
||||
if os.path.exists(pkgdir): # pragma: no cover (go<1.10)
|
||||
rmtree(pkgdir)
|
||||
env = dict(os.environ, GOPATH=gopath)
|
||||
env.pop('GOBIN', None)
|
||||
if version != 'system':
|
||||
env['GOROOT'] = os.path.join(env_dir, '.go')
|
||||
env['PATH'] = os.pathsep.join((
|
||||
os.path.join(env_dir, '.go', 'bin'), os.environ['PATH'],
|
||||
))
|
||||
|
||||
helpers.run_setup_cmd(prefix, ('go', 'install', './...'), env=env)
|
||||
for dependency in additional_dependencies:
|
||||
helpers.run_setup_cmd(prefix, ('go', 'install', dependency), env=env)
|
||||
|
||||
def run_hook(
|
||||
hook: Hook,
|
||||
file_args: Sequence[str],
|
||||
color: bool,
|
||||
) -> tuple[int, bytes]:
|
||||
with in_env(hook.prefix):
|
||||
return helpers.run_xargs(hook, hook.cmd, file_args, color=color)
|
||||
# save some disk space -- we don't need this after installation
|
||||
pkgdir = os.path.join(env_dir, 'pkg')
|
||||
if os.path.exists(pkgdir): # pragma: no branch (always true on windows?)
|
||||
rmtree(pkgdir)
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
import multiprocessing
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import shlex
|
||||
from typing import Any
|
||||
from typing import Generator
|
||||
from typing import NoReturn
|
||||
from typing import overload
|
||||
from typing import Sequence
|
||||
|
||||
import pre_commit.constants as C
|
||||
from pre_commit import parse_shebang
|
||||
from pre_commit.hook import Hook
|
||||
from pre_commit.prefix import Prefix
|
||||
from pre_commit.util import cmd_output_b
|
||||
from pre_commit.xargs import xargs
|
||||
|
@ -48,17 +49,8 @@ def run_setup_cmd(prefix: Prefix, cmd: tuple[str, ...], **kwargs: Any) -> None:
|
|||
cmd_output_b(*cmd, cwd=prefix.prefix_dir, **kwargs)
|
||||
|
||||
|
||||
@overload
|
||||
def environment_dir(d: None, language_version: str) -> None: ...
|
||||
@overload
|
||||
def environment_dir(d: str, language_version: str) -> str: ...
|
||||
|
||||
|
||||
def environment_dir(d: str | None, language_version: str) -> str | None:
|
||||
if d is None:
|
||||
return None
|
||||
else:
|
||||
return f'{d}-{language_version}'
|
||||
def environment_dir(prefix: Prefix, d: str, language_version: str) -> str:
|
||||
return prefix.path(f'{d}-{language_version}')
|
||||
|
||||
|
||||
def assert_version_default(binary: str, version: str) -> None:
|
||||
|
@ -94,11 +86,16 @@ def no_install(
|
|||
version: str,
|
||||
additional_dependencies: Sequence[str],
|
||||
) -> NoReturn:
|
||||
raise AssertionError('This type is not installable')
|
||||
raise AssertionError('This language is not installable')
|
||||
|
||||
|
||||
def target_concurrency(hook: Hook) -> int:
|
||||
if hook.require_serial or 'PRE_COMMIT_NO_CONCURRENCY' in os.environ:
|
||||
@contextlib.contextmanager
|
||||
def no_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
||||
yield
|
||||
|
||||
|
||||
def target_concurrency() -> int:
|
||||
if 'PRE_COMMIT_NO_CONCURRENCY' in os.environ:
|
||||
return 1
|
||||
else:
|
||||
# Travis appears to have a bunch of CPUs, but we can't use them all.
|
||||
|
@ -122,13 +119,40 @@ def _shuffled(seq: Sequence[str]) -> list[str]:
|
|||
|
||||
|
||||
def run_xargs(
|
||||
hook: Hook,
|
||||
cmd: tuple[str, ...],
|
||||
file_args: Sequence[str],
|
||||
**kwargs: Any,
|
||||
*,
|
||||
require_serial: bool,
|
||||
color: bool,
|
||||
) -> tuple[int, bytes]:
|
||||
# Shuffle the files so that they more evenly fill out the xargs partitions,
|
||||
# but do it deterministically in case a hook cares about ordering.
|
||||
file_args = _shuffled(file_args)
|
||||
kwargs['target_concurrency'] = target_concurrency(hook)
|
||||
return xargs(cmd, file_args, **kwargs)
|
||||
if require_serial:
|
||||
jobs = 1
|
||||
else:
|
||||
# Shuffle the files so that they more evenly fill out the xargs
|
||||
# partitions, but do it deterministically in case a hook cares about
|
||||
# ordering.
|
||||
file_args = _shuffled(file_args)
|
||||
jobs = target_concurrency()
|
||||
return xargs(cmd, file_args, target_concurrency=jobs, color=color)
|
||||
|
||||
|
||||
def hook_cmd(entry: str, args: Sequence[str]) -> tuple[str, ...]:
|
||||
return (*shlex.split(entry), *args)
|
||||
|
||||
|
||||
def basic_run_hook(
|
||||
prefix: Prefix,
|
||||
entry: str,
|
||||
args: Sequence[str],
|
||||
file_args: Sequence[str],
|
||||
*,
|
||||
is_local: bool,
|
||||
require_serial: bool,
|
||||
color: bool,
|
||||
) -> tuple[int, bytes]:
|
||||
return run_xargs(
|
||||
hook_cmd(entry, args),
|
||||
file_args,
|
||||
require_serial=require_serial,
|
||||
color=color,
|
||||
)
|
||||
|
|
|
@ -6,19 +6,17 @@ import sys
|
|||
from typing import Generator
|
||||
from typing import Sequence
|
||||
|
||||
import pre_commit.constants as C
|
||||
from pre_commit.envcontext import envcontext
|
||||
from pre_commit.envcontext import PatchesT
|
||||
from pre_commit.envcontext import Var
|
||||
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
|
||||
|
||||
ENVIRONMENT_DIR = 'lua_env'
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
health_check = helpers.basic_health_check
|
||||
run_hook = helpers.basic_run_hook
|
||||
|
||||
|
||||
def _get_lua_version() -> str: # pragma: win32 no cover
|
||||
|
@ -45,14 +43,10 @@ def get_env_patch(d: str) -> PatchesT: # pragma: win32 no cover
|
|||
)
|
||||
|
||||
|
||||
def _envdir(prefix: Prefix) -> str: # pragma: win32 no cover
|
||||
directory = helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT)
|
||||
return prefix.path(directory)
|
||||
|
||||
|
||||
@contextlib.contextmanager # pragma: win32 no cover
|
||||
def in_env(prefix: Prefix) -> Generator[None, None, None]:
|
||||
with envcontext(get_env_patch(_envdir(prefix))):
|
||||
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
|
||||
|
||||
|
||||
|
@ -63,29 +57,19 @@ def install_environment(
|
|||
) -> None: # pragma: win32 no cover
|
||||
helpers.assert_version_default('lua', version)
|
||||
|
||||
envdir = _envdir(prefix)
|
||||
with clean_path_on_failure(envdir):
|
||||
with in_env(prefix):
|
||||
# luarocks doesn't bootstrap a tree prior to installing
|
||||
# so ensure the directory exists.
|
||||
os.makedirs(envdir, exist_ok=True)
|
||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||
with in_env(prefix, version):
|
||||
# luarocks doesn't bootstrap a tree prior to installing
|
||||
# so ensure the directory exists.
|
||||
os.makedirs(envdir, exist_ok=True)
|
||||
|
||||
# Older luarocks (e.g., 2.4.2) expect the rockspec as an arg
|
||||
for rockspec in prefix.star('.rockspec'):
|
||||
make_cmd = ('luarocks', '--tree', envdir, 'make', rockspec)
|
||||
helpers.run_setup_cmd(prefix, make_cmd)
|
||||
# Older luarocks (e.g., 2.4.2) expect the rockspec as an arg
|
||||
for rockspec in prefix.star('.rockspec'):
|
||||
make_cmd = ('luarocks', '--tree', envdir, 'make', rockspec)
|
||||
helpers.run_setup_cmd(prefix, make_cmd)
|
||||
|
||||
# luarocks can't install multiple packages at once
|
||||
# so install them individually.
|
||||
for dependency in additional_dependencies:
|
||||
cmd = ('luarocks', '--tree', envdir, 'install', dependency)
|
||||
helpers.run_setup_cmd(prefix, cmd)
|
||||
|
||||
|
||||
def run_hook(
|
||||
hook: Hook,
|
||||
file_args: Sequence[str],
|
||||
color: bool,
|
||||
) -> tuple[int, bytes]: # pragma: win32 no cover
|
||||
with in_env(hook.prefix):
|
||||
return helpers.run_xargs(hook, hook.cmd, file_args, color=color)
|
||||
# luarocks can't install multiple packages at once
|
||||
# so install them individually.
|
||||
for dependency in additional_dependencies:
|
||||
cmd = ('luarocks', '--tree', envdir, 'install', dependency)
|
||||
helpers.run_setup_cmd(prefix, cmd)
|
||||
|
|
|
@ -12,16 +12,15 @@ from pre_commit.envcontext import envcontext
|
|||
from pre_commit.envcontext import PatchesT
|
||||
from pre_commit.envcontext import UNSET
|
||||
from pre_commit.envcontext import Var
|
||||
from pre_commit.hook import Hook
|
||||
from pre_commit.languages import helpers
|
||||
from pre_commit.languages.python import bin_dir
|
||||
from pre_commit.prefix import Prefix
|
||||
from pre_commit.util import clean_path_on_failure
|
||||
from pre_commit.util import cmd_output
|
||||
from pre_commit.util import cmd_output_b
|
||||
from pre_commit.util import rmtree
|
||||
|
||||
ENVIRONMENT_DIR = 'node_env'
|
||||
run_hook = helpers.basic_run_hook
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=1)
|
||||
|
@ -37,11 +36,6 @@ def get_default_version() -> str:
|
|||
return C.DEFAULT
|
||||
|
||||
|
||||
def _envdir(prefix: Prefix, version: str) -> str:
|
||||
directory = helpers.environment_dir(ENVIRONMENT_DIR, version)
|
||||
return prefix.path(directory)
|
||||
|
||||
|
||||
def get_env_patch(venv: str) -> PatchesT:
|
||||
if sys.platform == 'cygwin': # pragma: no cover
|
||||
_, win_venv, _ = cmd_output('cygpath', '-w', venv)
|
||||
|
@ -65,11 +59,9 @@ def get_env_patch(venv: str) -> PatchesT:
|
|||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_env(
|
||||
prefix: Prefix,
|
||||
language_version: str,
|
||||
) -> Generator[None, None, None]:
|
||||
with envcontext(get_env_patch(_envdir(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
|
||||
|
||||
|
||||
|
@ -85,47 +77,34 @@ def health_check(prefix: Prefix, language_version: str) -> str | None:
|
|||
def install_environment(
|
||||
prefix: Prefix, version: str, additional_dependencies: Sequence[str],
|
||||
) -> None:
|
||||
additional_dependencies = tuple(additional_dependencies)
|
||||
assert prefix.exists('package.json')
|
||||
envdir = _envdir(prefix, version)
|
||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||
|
||||
# https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx?f=255&MSPPError=-2147217396#maxpath
|
||||
if sys.platform == 'win32': # pragma: no cover
|
||||
envdir = fr'\\?\{os.path.normpath(envdir)}'
|
||||
with clean_path_on_failure(envdir):
|
||||
cmd = [
|
||||
sys.executable, '-mnodeenv', '--prebuilt', '--clean-src', envdir,
|
||||
]
|
||||
if version != C.DEFAULT:
|
||||
cmd.extend(['-n', version])
|
||||
cmd_output_b(*cmd)
|
||||
cmd = [sys.executable, '-mnodeenv', '--prebuilt', '--clean-src', envdir]
|
||||
if version != C.DEFAULT:
|
||||
cmd.extend(['-n', version])
|
||||
cmd_output_b(*cmd)
|
||||
|
||||
with in_env(prefix, version):
|
||||
# https://npm.community/t/npm-install-g-git-vs-git-clone-cd-npm-install-g/5449
|
||||
# install as if we installed from git
|
||||
with in_env(prefix, version):
|
||||
# https://npm.community/t/npm-install-g-git-vs-git-clone-cd-npm-install-g/5449
|
||||
# install as if we installed from git
|
||||
|
||||
local_install_cmd = (
|
||||
'npm', 'install', '--dev', '--prod',
|
||||
'--ignore-prepublish', '--no-progress', '--no-save',
|
||||
)
|
||||
helpers.run_setup_cmd(prefix, local_install_cmd)
|
||||
local_install_cmd = (
|
||||
'npm', 'install', '--dev', '--prod',
|
||||
'--ignore-prepublish', '--no-progress', '--no-save',
|
||||
)
|
||||
helpers.run_setup_cmd(prefix, local_install_cmd)
|
||||
|
||||
_, pkg, _ = cmd_output('npm', 'pack', cwd=prefix.prefix_dir)
|
||||
pkg = prefix.path(pkg.strip())
|
||||
_, pkg, _ = cmd_output('npm', 'pack', cwd=prefix.prefix_dir)
|
||||
pkg = prefix.path(pkg.strip())
|
||||
|
||||
install = ('npm', 'install', '-g', pkg, *additional_dependencies)
|
||||
helpers.run_setup_cmd(prefix, install)
|
||||
install = ('npm', 'install', '-g', pkg, *additional_dependencies)
|
||||
helpers.run_setup_cmd(prefix, install)
|
||||
|
||||
# clean these up after installation
|
||||
if prefix.exists('node_modules'): # pragma: win32 no cover
|
||||
rmtree(prefix.path('node_modules'))
|
||||
os.remove(pkg)
|
||||
|
||||
|
||||
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, hook.cmd, file_args, color=color)
|
||||
# clean these up after installation
|
||||
if prefix.exists('node_modules'): # pragma: win32 no cover
|
||||
rmtree(prefix.path('node_modules'))
|
||||
os.remove(pkg)
|
||||
|
|
|
@ -9,19 +9,13 @@ from typing import Sequence
|
|||
from pre_commit.envcontext import envcontext
|
||||
from pre_commit.envcontext import PatchesT
|
||||
from pre_commit.envcontext import Var
|
||||
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
|
||||
|
||||
ENVIRONMENT_DIR = 'perl_env'
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
health_check = helpers.basic_health_check
|
||||
|
||||
|
||||
def _envdir(prefix: Prefix, version: str) -> str:
|
||||
directory = helpers.environment_dir(ENVIRONMENT_DIR, version)
|
||||
return prefix.path(directory)
|
||||
run_hook = helpers.basic_run_hook
|
||||
|
||||
|
||||
def get_env_patch(venv: str) -> PatchesT:
|
||||
|
@ -39,11 +33,9 @@ def get_env_patch(venv: str) -> PatchesT:
|
|||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_env(
|
||||
prefix: Prefix,
|
||||
language_version: str,
|
||||
) -> Generator[None, None, None]:
|
||||
with envcontext(get_env_patch(_envdir(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
|
||||
|
||||
|
||||
|
@ -52,17 +44,7 @@ def install_environment(
|
|||
) -> None:
|
||||
helpers.assert_version_default('perl', version)
|
||||
|
||||
with clean_path_on_failure(_envdir(prefix, version)):
|
||||
with in_env(prefix, version):
|
||||
helpers.run_setup_cmd(
|
||||
prefix, ('cpan', '-T', '.', *additional_dependencies),
|
||||
)
|
||||
|
||||
|
||||
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, hook.cmd, file_args, color=color)
|
||||
with in_env(prefix, version):
|
||||
helpers.run_setup_cmd(
|
||||
prefix, ('cpan', '-T', '.', *additional_dependencies),
|
||||
)
|
||||
|
|
|
@ -8,14 +8,15 @@ from typing import Pattern
|
|||
from typing import Sequence
|
||||
|
||||
from pre_commit import output
|
||||
from pre_commit.hook import Hook
|
||||
from pre_commit.languages import helpers
|
||||
from pre_commit.prefix import Prefix
|
||||
from pre_commit.xargs import xargs
|
||||
|
||||
ENVIRONMENT_DIR = None
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
health_check = helpers.basic_health_check
|
||||
install_environment = helpers.no_install
|
||||
in_env = helpers.no_env
|
||||
|
||||
|
||||
def _process_filename_by_line(pattern: Pattern[bytes], filename: str) -> int:
|
||||
|
@ -87,12 +88,17 @@ FNS = {
|
|||
|
||||
|
||||
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]:
|
||||
exe = (sys.executable, '-m', __name__) + tuple(hook.args) + (hook.entry,)
|
||||
return xargs(exe, file_args, color=color)
|
||||
cmd = (sys.executable, '-m', __name__, *args, entry)
|
||||
return xargs(cmd, file_args, color=color)
|
||||
|
||||
|
||||
def main(argv: Sequence[str] | None = None) -> int:
|
||||
|
|
|
@ -12,17 +12,16 @@ from pre_commit.envcontext import envcontext
|
|||
from pre_commit.envcontext import PatchesT
|
||||
from pre_commit.envcontext import UNSET
|
||||
from pre_commit.envcontext import Var
|
||||
from pre_commit.hook import Hook
|
||||
from pre_commit.languages import helpers
|
||||
from pre_commit.parse_shebang import find_executable
|
||||
from pre_commit.prefix import Prefix
|
||||
from pre_commit.util import CalledProcessError
|
||||
from pre_commit.util import clean_path_on_failure
|
||||
from pre_commit.util import cmd_output
|
||||
from pre_commit.util import cmd_output_b
|
||||
from pre_commit.util import win_exe
|
||||
|
||||
ENVIRONMENT_DIR = 'py_env'
|
||||
run_hook = helpers.basic_run_hook
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=None)
|
||||
|
@ -153,19 +152,14 @@ def norm_version(version: str) -> str | None:
|
|||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_env(
|
||||
prefix: Prefix,
|
||||
language_version: str,
|
||||
) -> Generator[None, None, None]:
|
||||
directory = helpers.environment_dir(ENVIRONMENT_DIR, language_version)
|
||||
envdir = prefix.path(directory)
|
||||
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 health_check(prefix: Prefix, language_version: str) -> str | None:
|
||||
directory = helpers.environment_dir(ENVIRONMENT_DIR, language_version)
|
||||
envdir = prefix.path(directory)
|
||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, language_version)
|
||||
pyvenv_cfg = os.path.join(envdir, 'pyvenv.cfg')
|
||||
|
||||
# created with "old" virtualenv
|
||||
|
@ -208,23 +202,13 @@ def install_environment(
|
|||
version: str,
|
||||
additional_dependencies: Sequence[str],
|
||||
) -> None:
|
||||
envdir = prefix.path(helpers.environment_dir(ENVIRONMENT_DIR, version))
|
||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||
venv_cmd = [sys.executable, '-mvirtualenv', envdir]
|
||||
python = norm_version(version)
|
||||
if python is not None:
|
||||
venv_cmd.extend(('-p', python))
|
||||
install_cmd = ('python', '-mpip', 'install', '.', *additional_dependencies)
|
||||
|
||||
with clean_path_on_failure(envdir):
|
||||
cmd_output_b(*venv_cmd, cwd='/')
|
||||
with in_env(prefix, version):
|
||||
helpers.run_setup_cmd(prefix, install_cmd)
|
||||
|
||||
|
||||
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, hook.cmd, file_args, color=color)
|
||||
cmd_output_b(*venv_cmd, cwd='/')
|
||||
with in_env(prefix, version):
|
||||
helpers.run_setup_cmd(prefix, install_cmd)
|
||||
|
|
|
@ -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'))
|
||||
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(), '");}})'
|
||||
)
|
||||
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,
|
||||
r_code_inst_environment = f"""\
|
||||
prefix_dir <- {prefix.prefix_dir!r}
|
||||
options(
|
||||
repos = c(CRAN = "https://cran.rstudio.com"),
|
||||
renv.consent = TRUE
|
||||
)
|
||||
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,
|
||||
)
|
||||
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,
|
||||
)
|
||||
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,
|
||||
)
|
||||
|
|
|
@ -13,15 +13,14 @@ from pre_commit.envcontext import envcontext
|
|||
from pre_commit.envcontext import PatchesT
|
||||
from pre_commit.envcontext import UNSET
|
||||
from pre_commit.envcontext import Var
|
||||
from pre_commit.hook import Hook
|
||||
from pre_commit.languages import helpers
|
||||
from pre_commit.prefix import Prefix
|
||||
from pre_commit.util import CalledProcessError
|
||||
from pre_commit.util import clean_path_on_failure
|
||||
from pre_commit.util import resource_bytesio
|
||||
|
||||
ENVIRONMENT_DIR = 'rbenv'
|
||||
health_check = helpers.basic_health_check
|
||||
run_hook = helpers.basic_run_hook
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=1)
|
||||
|
@ -40,6 +39,7 @@ def get_env_patch(
|
|||
('GEM_HOME', os.path.join(venv, 'gems')),
|
||||
('GEM_PATH', UNSET),
|
||||
('BUNDLE_IGNORE_CONFIG', '1'),
|
||||
('BUNDLE_GEMFILE', os.devnull),
|
||||
)
|
||||
if language_version == 'system':
|
||||
patches += (
|
||||
|
@ -68,14 +68,9 @@ def get_env_patch(
|
|||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_env(
|
||||
prefix: Prefix,
|
||||
language_version: str,
|
||||
) -> Generator[None, None, None]:
|
||||
envdir = prefix.path(
|
||||
helpers.environment_dir(ENVIRONMENT_DIR, language_version),
|
||||
)
|
||||
with envcontext(get_env_patch(envdir, 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, version)):
|
||||
yield
|
||||
|
||||
|
||||
|
@ -89,14 +84,14 @@ def _install_rbenv(
|
|||
prefix: Prefix,
|
||||
version: str,
|
||||
) -> None: # pragma: win32 no cover
|
||||
directory = helpers.environment_dir(ENVIRONMENT_DIR, version)
|
||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||
|
||||
_extract_resource('rbenv.tar.gz', prefix.path('.'))
|
||||
shutil.move(prefix.path('rbenv'), prefix.path(directory))
|
||||
shutil.move(prefix.path('rbenv'), envdir)
|
||||
|
||||
# Only install ruby-build if the version is specified
|
||||
if version != C.DEFAULT:
|
||||
plugins_dir = prefix.path(directory, 'plugins')
|
||||
plugins_dir = os.path.join(envdir, 'plugins')
|
||||
_extract_resource('ruby-download.tar.gz', plugins_dir)
|
||||
_extract_resource('ruby-build.tar.gz', plugins_dir)
|
||||
|
||||
|
@ -115,39 +110,27 @@ def _install_ruby(
|
|||
def install_environment(
|
||||
prefix: Prefix, version: str, additional_dependencies: Sequence[str],
|
||||
) -> None:
|
||||
additional_dependencies = tuple(additional_dependencies)
|
||||
directory = helpers.environment_dir(ENVIRONMENT_DIR, version)
|
||||
with clean_path_on_failure(prefix.path(directory)):
|
||||
if version != 'system': # pragma: win32 no cover
|
||||
_install_rbenv(prefix, version)
|
||||
with in_env(prefix, version):
|
||||
# Need to call this before installing so rbenv's directories
|
||||
# are set up
|
||||
helpers.run_setup_cmd(prefix, ('rbenv', 'init', '-'))
|
||||
if version != C.DEFAULT:
|
||||
_install_ruby(prefix, version)
|
||||
# Need to call this after installing to set up the shims
|
||||
helpers.run_setup_cmd(prefix, ('rbenv', 'rehash'))
|
||||
|
||||
if version != 'system': # pragma: win32 no cover
|
||||
_install_rbenv(prefix, version)
|
||||
with in_env(prefix, version):
|
||||
helpers.run_setup_cmd(
|
||||
prefix, ('gem', 'build', *prefix.star('.gemspec')),
|
||||
)
|
||||
helpers.run_setup_cmd(
|
||||
prefix,
|
||||
(
|
||||
'gem', 'install',
|
||||
'--no-document', '--no-format-executable',
|
||||
'--no-user-install',
|
||||
*prefix.star('.gem'), *additional_dependencies,
|
||||
),
|
||||
)
|
||||
# Need to call this before installing so rbenv's directories
|
||||
# are set up
|
||||
helpers.run_setup_cmd(prefix, ('rbenv', 'init', '-'))
|
||||
if version != C.DEFAULT:
|
||||
_install_ruby(prefix, version)
|
||||
# Need to call this after installing to set up the shims
|
||||
helpers.run_setup_cmd(prefix, ('rbenv', 'rehash'))
|
||||
|
||||
|
||||
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, hook.cmd, file_args, color=color)
|
||||
with in_env(prefix, version):
|
||||
helpers.run_setup_cmd(
|
||||
prefix, ('gem', 'build', *prefix.star('.gemspec')),
|
||||
)
|
||||
helpers.run_setup_cmd(
|
||||
prefix,
|
||||
(
|
||||
'gem', 'install',
|
||||
'--no-document', '--no-format-executable',
|
||||
'--no-user-install',
|
||||
*prefix.star('.gem'), *additional_dependencies,
|
||||
),
|
||||
)
|
||||
|
|
|
@ -15,16 +15,15 @@ from pre_commit import parse_shebang
|
|||
from pre_commit.envcontext import envcontext
|
||||
from pre_commit.envcontext import PatchesT
|
||||
from pre_commit.envcontext import Var
|
||||
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 make_executable
|
||||
from pre_commit.util import win_exe
|
||||
|
||||
ENVIRONMENT_DIR = 'rustenv'
|
||||
health_check = helpers.basic_health_check
|
||||
run_hook = helpers.basic_run_hook
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=1)
|
||||
|
@ -49,11 +48,6 @@ def _rust_toolchain(language_version: str) -> str:
|
|||
return language_version
|
||||
|
||||
|
||||
def _envdir(prefix: Prefix, version: str) -> str:
|
||||
directory = helpers.environment_dir(ENVIRONMENT_DIR, version)
|
||||
return prefix.path(directory)
|
||||
|
||||
|
||||
def get_env_patch(target_dir: str, version: str) -> PatchesT:
|
||||
return (
|
||||
('CARGO_HOME', target_dir),
|
||||
|
@ -68,13 +62,9 @@ def get_env_patch(target_dir: str, version: str) -> PatchesT:
|
|||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_env(
|
||||
prefix: Prefix,
|
||||
language_version: str,
|
||||
) -> Generator[None, None, None]:
|
||||
with envcontext(
|
||||
get_env_patch(_envdir(prefix, language_version), 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, version)):
|
||||
yield
|
||||
|
||||
|
||||
|
@ -126,7 +116,7 @@ def install_environment(
|
|||
version: str,
|
||||
additional_dependencies: Sequence[str],
|
||||
) -> None:
|
||||
directory = _envdir(prefix, version)
|
||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||
|
||||
# There are two cases where we might want to specify more dependencies:
|
||||
# as dependencies for the library being built, and as binary packages
|
||||
|
@ -143,34 +133,24 @@ def install_environment(
|
|||
}
|
||||
lib_deps = set(additional_dependencies) - cli_deps
|
||||
|
||||
with clean_path_on_failure(directory):
|
||||
packages_to_install: set[tuple[str, ...]] = {('--path', '.')}
|
||||
for cli_dep in cli_deps:
|
||||
cli_dep = cli_dep[len('cli:'):]
|
||||
package, _, crate_version = cli_dep.partition(':')
|
||||
if crate_version != '':
|
||||
packages_to_install.add((package, '--version', crate_version))
|
||||
else:
|
||||
packages_to_install.add((package,))
|
||||
packages_to_install: set[tuple[str, ...]] = {('--path', '.')}
|
||||
for cli_dep in cli_deps:
|
||||
cli_dep = cli_dep[len('cli:'):]
|
||||
package, _, crate_version = cli_dep.partition(':')
|
||||
if crate_version != '':
|
||||
packages_to_install.add((package, '--version', crate_version))
|
||||
else:
|
||||
packages_to_install.add((package,))
|
||||
|
||||
with in_env(prefix, version):
|
||||
if version != 'system':
|
||||
install_rust_with_toolchain(_rust_toolchain(version))
|
||||
with in_env(prefix, version):
|
||||
if version != 'system':
|
||||
install_rust_with_toolchain(_rust_toolchain(version))
|
||||
|
||||
if len(lib_deps) > 0:
|
||||
_add_dependencies(prefix, lib_deps)
|
||||
if len(lib_deps) > 0:
|
||||
_add_dependencies(prefix, lib_deps)
|
||||
|
||||
for args in packages_to_install:
|
||||
cmd_output_b(
|
||||
'cargo', 'install', '--bins', '--root', directory, *args,
|
||||
cwd=prefix.prefix_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, hook.cmd, file_args, color=color)
|
||||
for args in packages_to_install:
|
||||
cmd_output_b(
|
||||
'cargo', 'install', '--bins', '--root', envdir, *args,
|
||||
cwd=prefix.prefix_dir,
|
||||
)
|
||||
|
|
|
@ -2,19 +2,31 @@ from __future__ import annotations
|
|||
|
||||
from typing import Sequence
|
||||
|
||||
from pre_commit.hook import Hook
|
||||
from pre_commit.languages import helpers
|
||||
from pre_commit.prefix import Prefix
|
||||
|
||||
ENVIRONMENT_DIR = None
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
health_check = helpers.basic_health_check
|
||||
install_environment = helpers.no_install
|
||||
in_env = helpers.no_env
|
||||
|
||||
|
||||
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]:
|
||||
cmd = (hook.prefix.path(hook.cmd[0]), *hook.cmd[1:])
|
||||
return helpers.run_xargs(hook, cmd, file_args, color=color)
|
||||
cmd = helpers.hook_cmd(entry, args)
|
||||
cmd = (prefix.path(cmd[0]), *cmd[1:])
|
||||
return helpers.run_xargs(
|
||||
cmd,
|
||||
file_args,
|
||||
require_serial=require_serial,
|
||||
color=color,
|
||||
)
|
||||
|
|
|
@ -5,21 +5,20 @@ import os
|
|||
from typing import Generator
|
||||
from typing import Sequence
|
||||
|
||||
import pre_commit.constants as C
|
||||
from pre_commit.envcontext import envcontext
|
||||
from pre_commit.envcontext import PatchesT
|
||||
from pre_commit.envcontext import Var
|
||||
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
|
||||
|
||||
BUILD_DIR = '.build'
|
||||
BUILD_CONFIG = 'release'
|
||||
|
||||
ENVIRONMENT_DIR = 'swift_env'
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
health_check = helpers.basic_health_check
|
||||
BUILD_DIR = '.build'
|
||||
BUILD_CONFIG = 'release'
|
||||
run_hook = helpers.basic_run_hook
|
||||
|
||||
|
||||
def get_env_patch(venv: str) -> PatchesT: # pragma: win32 no cover
|
||||
|
@ -28,10 +27,8 @@ def get_env_patch(venv: str) -> PatchesT: # pragma: win32 no cover
|
|||
|
||||
|
||||
@contextlib.contextmanager # pragma: win32 no cover
|
||||
def in_env(prefix: Prefix) -> Generator[None, None, None]:
|
||||
envdir = prefix.path(
|
||||
helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT),
|
||||
)
|
||||
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
|
||||
|
||||
|
@ -41,25 +38,13 @@ def install_environment(
|
|||
) -> None: # pragma: win32 no cover
|
||||
helpers.assert_version_default('swift', version)
|
||||
helpers.assert_no_additional_deps('swift', additional_dependencies)
|
||||
directory = prefix.path(
|
||||
helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT),
|
||||
)
|
||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||
|
||||
# Build the swift package
|
||||
with clean_path_on_failure(directory):
|
||||
os.mkdir(directory)
|
||||
cmd_output_b(
|
||||
'swift', 'build',
|
||||
'-C', prefix.prefix_dir,
|
||||
'-c', BUILD_CONFIG,
|
||||
'--build-path', os.path.join(directory, BUILD_DIR),
|
||||
)
|
||||
|
||||
|
||||
def run_hook(
|
||||
hook: Hook,
|
||||
file_args: Sequence[str],
|
||||
color: bool,
|
||||
) -> tuple[int, bytes]: # pragma: win32 no cover
|
||||
with in_env(hook.prefix):
|
||||
return helpers.run_xargs(hook, hook.cmd, file_args, color=color)
|
||||
os.mkdir(envdir)
|
||||
cmd_output_b(
|
||||
'swift', 'build',
|
||||
'-C', prefix.prefix_dir,
|
||||
'-c', BUILD_CONFIG,
|
||||
'--build-path', os.path.join(envdir, BUILD_DIR),
|
||||
)
|
||||
|
|
|
@ -1,20 +1,10 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import Sequence
|
||||
|
||||
from pre_commit.hook import Hook
|
||||
from pre_commit.languages import helpers
|
||||
|
||||
|
||||
ENVIRONMENT_DIR = None
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
health_check = helpers.basic_health_check
|
||||
install_environment = helpers.no_install
|
||||
|
||||
|
||||
def run_hook(
|
||||
hook: Hook,
|
||||
file_args: Sequence[str],
|
||||
color: bool,
|
||||
) -> tuple[int, bytes]:
|
||||
return helpers.run_xargs(hook, hook.cmd, file_args, color=color)
|
||||
in_env = helpers.no_env
|
||||
run_hook = helpers.basic_run_hook
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue