Add types to pre-commit

This commit is contained in:
Anthony Sottile 2020-01-10 23:32:28 -08:00
parent fa536a8693
commit 327ed924a3
62 changed files with 911 additions and 411 deletions

View file

@ -1,20 +1,29 @@
import contextlib
import os
from typing import Generator
from typing import Sequence
from typing import Tuple
from typing import TYPE_CHECKING
from pre_commit.envcontext import envcontext
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.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
if TYPE_CHECKING:
from pre_commit.repository import Hook
ENVIRONMENT_DIR = 'conda'
get_default_version = helpers.basic_get_default_version
healthy = helpers.basic_healthy
def get_env_patch(env):
def get_env_patch(env: str) -> PatchesT:
# On non-windows systems executable live in $CONDA_PREFIX/bin, on Windows
# they can be in $CONDA_PREFIX/bin, $CONDA_PREFIX/Library/bin,
# $CONDA_PREFIX/Scripts and $CONDA_PREFIX. Whereas the latter only
@ -34,14 +43,21 @@ def get_env_patch(env):
@contextlib.contextmanager
def in_env(prefix, language_version):
def in_env(
prefix: Prefix,
language_version: str,
) -> Generator[None, None, None]:
directory = helpers.environment_dir(ENVIRONMENT_DIR, language_version)
envdir = prefix.path(directory)
with envcontext(get_env_patch(envdir)):
yield
def install_environment(prefix, version, additional_dependencies):
def install_environment(
prefix: Prefix,
version: str,
additional_dependencies: Sequence[str],
) -> None:
helpers.assert_version_default('conda', version)
directory = helpers.environment_dir(ENVIRONMENT_DIR, version)
@ -58,7 +74,11 @@ def install_environment(prefix, version, additional_dependencies):
)
def run_hook(hook, file_args, color):
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 withot which is much quicker and produces a better
# output.

View file

@ -1,14 +1,18 @@
import hashlib
import os
from typing import Sequence
from typing import Tuple
from typing import TYPE_CHECKING
import pre_commit.constants as C
from pre_commit import five
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
if TYPE_CHECKING:
from pre_commit.repository import Hook
ENVIRONMENT_DIR = 'docker'
PRE_COMMIT_LABEL = 'PRE_COMMIT'
@ -16,16 +20,16 @@ get_default_version = helpers.basic_get_default_version
healthy = helpers.basic_healthy
def md5(s): # pragma: windows no cover
return hashlib.md5(five.to_bytes(s)).hexdigest()
def md5(s: str) -> str: # pragma: windows no cover
return hashlib.md5(s.encode()).hexdigest()
def docker_tag(prefix): # pragma: windows no cover
def docker_tag(prefix: Prefix) -> str: # pragma: windows no cover
md5sum = md5(os.path.basename(prefix.prefix_dir)).lower()
return f'pre-commit-{md5sum}'
def docker_is_running(): # pragma: windows no cover
def docker_is_running() -> bool: # pragma: windows no cover
try:
cmd_output_b('docker', 'ps')
except CalledProcessError:
@ -34,15 +38,17 @@ def docker_is_running(): # pragma: windows no cover
return True
def assert_docker_available(): # pragma: windows no cover
def assert_docker_available() -> None: # pragma: windows no cover
assert docker_is_running(), (
'Docker is either not running or not configured in this environment'
)
def build_docker_image(prefix, **kwargs): # pragma: windows no cover
pull = kwargs.pop('pull')
assert not kwargs, kwargs
def build_docker_image(
prefix: Prefix,
*,
pull: bool,
) -> None: # pragma: windows no cover
cmd: Tuple[str, ...] = (
'docker', 'build',
'--tag', docker_tag(prefix),
@ -56,8 +62,8 @@ def build_docker_image(prefix, **kwargs): # pragma: windows no cover
def install_environment(
prefix, version, additional_dependencies,
): # pragma: windows no cover
prefix: Prefix, version: str, additional_dependencies: Sequence[str],
) -> None: # pragma: windows no cover
helpers.assert_version_default('docker', version)
helpers.assert_no_additional_deps('docker', additional_dependencies)
assert_docker_available()
@ -73,14 +79,14 @@ def install_environment(
os.mkdir(directory)
def get_docker_user(): # pragma: windows no cover
def get_docker_user() -> str: # pragma: windows no cover
try:
return '{}:{}'.format(os.getuid(), os.getgid())
except AttributeError:
return '1000:1000'
def docker_cmd(): # pragma: windows no cover
def docker_cmd() -> Tuple[str, ...]: # pragma: windows no cover
return (
'docker', 'run',
'--rm',
@ -93,7 +99,11 @@ def docker_cmd(): # pragma: windows no cover
)
def run_hook(hook, file_args, color): # pragma: windows no cover
def run_hook(
hook: 'Hook',
file_args: Sequence[str],
color: bool,
) -> Tuple[int, bytes]: # pragma: windows no cover
assert_docker_available()
# Rebuild the docker image in case it has gone missing, as many people do
# automated cleanup of docker images.

View file

@ -1,7 +1,13 @@
from typing import Sequence
from typing import Tuple
from typing import TYPE_CHECKING
from pre_commit.languages import helpers
from pre_commit.languages.docker import assert_docker_available
from pre_commit.languages.docker import docker_cmd
if TYPE_CHECKING:
from pre_commit.repository import Hook
ENVIRONMENT_DIR = None
get_default_version = helpers.basic_get_default_version
@ -9,7 +15,11 @@ healthy = helpers.basic_healthy
install_environment = helpers.no_install
def run_hook(hook, file_args, color): # pragma: windows no cover
def run_hook(
hook: 'Hook',
file_args: Sequence[str],
color: bool,
) -> Tuple[int, bytes]: # pragma: windows no cover
assert_docker_available()
cmd = docker_cmd() + hook.cmd
return helpers.run_xargs(hook, cmd, file_args, color=color)

View file

@ -1,5 +1,11 @@
from typing import Sequence
from typing import Tuple
from typing import TYPE_CHECKING
from pre_commit.languages import helpers
if TYPE_CHECKING:
from pre_commit.repository import Hook
ENVIRONMENT_DIR = None
get_default_version = helpers.basic_get_default_version
@ -7,7 +13,11 @@ healthy = helpers.basic_healthy
install_environment = helpers.no_install
def run_hook(hook, file_args, color):
def run_hook(
hook: 'Hook',
file_args: Sequence[str],
color: bool,
) -> Tuple[int, bytes]:
out = hook.entry.encode('UTF-8') + b'\n\n'
out += b'\n'.join(f.encode('UTF-8') for f in file_args) + b'\n'
return 1, out

View file

@ -1,31 +1,39 @@
import contextlib
import os.path
import sys
from typing import Generator
from typing import Sequence
from typing import Tuple
from typing import TYPE_CHECKING
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.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
if TYPE_CHECKING:
from pre_commit.repository import Hook
ENVIRONMENT_DIR = 'golangenv'
get_default_version = helpers.basic_get_default_version
healthy = helpers.basic_healthy
def get_env_patch(venv):
def get_env_patch(venv: str) -> PatchesT:
return (
('PATH', (os.path.join(venv, 'bin'), os.pathsep, Var('PATH'))),
)
@contextlib.contextmanager
def in_env(prefix):
def in_env(prefix: Prefix) -> Generator[None, None, None]:
envdir = prefix.path(
helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT),
)
@ -33,7 +41,7 @@ def in_env(prefix):
yield
def guess_go_dir(remote_url):
def guess_go_dir(remote_url: str) -> str:
if remote_url.endswith('.git'):
remote_url = remote_url[:-1 * len('.git')]
looks_like_url = (
@ -49,7 +57,11 @@ def guess_go_dir(remote_url):
return 'unknown_src_dir'
def install_environment(prefix, version, additional_dependencies):
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),
@ -79,6 +91,10 @@ def install_environment(prefix, version, additional_dependencies):
rmtree(pkgdir)
def run_hook(hook, file_args, color):
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)

View file

@ -1,33 +1,54 @@
import multiprocessing
import os
import random
from typing import Any
from typing import List
from typing import NoReturn
from typing import Optional
from typing import overload
from typing import Sequence
from typing import Tuple
from typing import TYPE_CHECKING
import pre_commit.constants as C
from pre_commit.prefix import Prefix
from pre_commit.util import cmd_output_b
from pre_commit.xargs import xargs
if TYPE_CHECKING:
from pre_commit.repository import Hook
FIXED_RANDOM_SEED = 1542676186
def run_setup_cmd(prefix, cmd):
def run_setup_cmd(prefix: Prefix, cmd: Tuple[str, ...]) -> None:
cmd_output_b(*cmd, cwd=prefix.prefix_dir)
def environment_dir(ENVIRONMENT_DIR, language_version):
if ENVIRONMENT_DIR is None:
@overload
def environment_dir(d: None, language_version: str) -> None: ...
@overload
def environment_dir(d: str, language_version: str) -> str: ...
def environment_dir(d: Optional[str], language_version: str) -> Optional[str]:
if d is None:
return None
else:
return f'{ENVIRONMENT_DIR}-{language_version}'
return f'{d}-{language_version}'
def assert_version_default(binary, version):
def assert_version_default(binary: str, version: str) -> None:
if version != C.DEFAULT:
raise AssertionError(
f'For now, pre-commit requires system-installed {binary}',
)
def assert_no_additional_deps(lang, additional_deps):
def assert_no_additional_deps(
lang: str,
additional_deps: Sequence[str],
) -> None:
if additional_deps:
raise AssertionError(
'For now, pre-commit does not support '
@ -35,19 +56,23 @@ def assert_no_additional_deps(lang, additional_deps):
)
def basic_get_default_version():
def basic_get_default_version() -> str:
return C.DEFAULT
def basic_healthy(prefix, language_version):
def basic_healthy(prefix: Prefix, language_version: str) -> bool:
return True
def no_install(prefix, version, additional_dependencies):
def no_install(
prefix: Prefix,
version: str,
additional_dependencies: Sequence[str],
) -> NoReturn:
raise AssertionError('This type is not installable')
def target_concurrency(hook):
def target_concurrency(hook: 'Hook') -> int:
if hook.require_serial or 'PRE_COMMIT_NO_CONCURRENCY' in os.environ:
return 1
else:
@ -61,8 +86,8 @@ def target_concurrency(hook):
return 1
def _shuffled(seq):
"""Deterministically shuffle identically under both py2 + py3."""
def _shuffled(seq: Sequence[str]) -> List[str]:
"""Deterministically shuffle"""
fixed_random = random.Random()
fixed_random.seed(FIXED_RANDOM_SEED, version=1)
@ -71,7 +96,12 @@ def _shuffled(seq):
return seq
def run_xargs(hook, cmd, file_args, **kwargs):
def run_xargs(
hook: 'Hook',
cmd: Tuple[str, ...],
file_args: Sequence[str],
**kwargs: Any,
) -> 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)

View file

@ -1,28 +1,36 @@
import contextlib
import os
import sys
from typing import Generator
from typing import Sequence
from typing import Tuple
from typing import TYPE_CHECKING
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.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
if TYPE_CHECKING:
from pre_commit.repository import Hook
ENVIRONMENT_DIR = 'node_env'
get_default_version = helpers.basic_get_default_version
healthy = helpers.basic_healthy
def _envdir(prefix, version):
def _envdir(prefix: Prefix, version: str) -> str:
directory = helpers.environment_dir(ENVIRONMENT_DIR, version)
return prefix.path(directory)
def get_env_patch(venv): # pragma: windows no cover
def get_env_patch(venv: str) -> PatchesT: # pragma: windows no cover
if sys.platform == 'cygwin': # pragma: no cover
_, win_venv, _ = cmd_output('cygpath', '-w', venv)
install_prefix = r'{}\bin'.format(win_venv.strip())
@ -43,14 +51,17 @@ def get_env_patch(venv): # pragma: windows no cover
@contextlib.contextmanager
def in_env(prefix, language_version): # pragma: windows no cover
def in_env(
prefix: Prefix,
language_version: str,
) -> Generator[None, None, None]: # pragma: windows no cover
with envcontext(get_env_patch(_envdir(prefix, language_version))):
yield
def install_environment(
prefix, version, additional_dependencies,
): # pragma: windows no cover
prefix: Prefix, version: str, additional_dependencies: Sequence[str],
) -> None: # pragma: windows no cover
additional_dependencies = tuple(additional_dependencies)
assert prefix.exists('package.json')
envdir = _envdir(prefix, version)
@ -76,6 +87,10 @@ def install_environment(
)
def run_hook(hook, file_args, color): # pragma: windows no cover
def run_hook(
hook: 'Hook',
file_args: Sequence[str],
color: bool,
) -> Tuple[int, bytes]: # pragma: windows no cover
with in_env(hook.prefix, hook.language_version):
return helpers.run_xargs(hook, hook.cmd, file_args, color=color)

View file

@ -1,11 +1,18 @@
import argparse
import re
import sys
from typing import Optional
from typing import Pattern
from typing import Sequence
from typing import Tuple
from typing import TYPE_CHECKING
from pre_commit import output
from pre_commit.languages import helpers
from pre_commit.xargs import xargs
if TYPE_CHECKING:
from pre_commit.repository import Hook
ENVIRONMENT_DIR = None
get_default_version = helpers.basic_get_default_version
@ -13,7 +20,7 @@ healthy = helpers.basic_healthy
install_environment = helpers.no_install
def _process_filename_by_line(pattern, filename):
def _process_filename_by_line(pattern: Pattern[bytes], filename: str) -> int:
retv = 0
with open(filename, 'rb') as f:
for line_no, line in enumerate(f, start=1):
@ -24,7 +31,7 @@ def _process_filename_by_line(pattern, filename):
return retv
def _process_filename_at_once(pattern, filename):
def _process_filename_at_once(pattern: Pattern[bytes], filename: str) -> int:
retv = 0
with open(filename, 'rb') as f:
contents = f.read()
@ -41,12 +48,16 @@ def _process_filename_at_once(pattern, filename):
return retv
def run_hook(hook, file_args, color):
def run_hook(
hook: 'Hook',
file_args: Sequence[str],
color: bool,
) -> Tuple[int, bytes]:
exe = (sys.executable, '-m', __name__) + tuple(hook.args) + (hook.entry,)
return xargs(exe, file_args, color=color)
def main(argv=None):
def main(argv: Optional[Sequence[str]] = None) -> int:
parser = argparse.ArgumentParser(
description=(
'grep-like finder using python regexes. Unlike grep, this tool '

View file

@ -2,29 +2,40 @@ import contextlib
import functools
import os
import sys
from typing import Callable
from typing import ContextManager
from typing import Generator
from typing import Optional
from typing import Sequence
from typing import Tuple
from typing import TYPE_CHECKING
import pre_commit.constants as C
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.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
if TYPE_CHECKING:
from pre_commit.repository import Hook
ENVIRONMENT_DIR = 'py_env'
def bin_dir(venv):
def bin_dir(venv: str) -> str:
"""On windows there's a different directory for the virtualenv"""
bin_part = 'Scripts' if os.name == 'nt' else 'bin'
return os.path.join(venv, bin_part)
def get_env_patch(venv):
def get_env_patch(venv: str) -> PatchesT:
return (
('PYTHONHOME', UNSET),
('VIRTUAL_ENV', venv),
@ -32,7 +43,9 @@ def get_env_patch(venv):
)
def _find_by_py_launcher(version): # pragma: no cover (windows only)
def _find_by_py_launcher(
version: str,
) -> Optional[str]: # pragma: no cover (windows only)
if version.startswith('python'):
try:
return cmd_output(
@ -41,14 +54,16 @@ def _find_by_py_launcher(version): # pragma: no cover (windows only)
)[1].strip()
except CalledProcessError:
pass
return None
def _find_by_sys_executable():
def _norm(path):
def _find_by_sys_executable() -> Optional[str]:
def _norm(path: str) -> Optional[str]:
_, exe = os.path.split(path.lower())
exe, _, _ = exe.partition('.exe')
if find_executable(exe) and exe not in {'python', 'pythonw'}:
return exe
return None
# On linux, I see these common sys.executables:
#
@ -66,7 +81,7 @@ def _find_by_sys_executable():
@functools.lru_cache(maxsize=1)
def get_default_version(): # pragma: no cover (platform dependent)
def get_default_version() -> str: # pragma: no cover (platform dependent)
# First attempt from `sys.executable` (or the realpath)
exe = _find_by_sys_executable()
if exe:
@ -88,7 +103,7 @@ def get_default_version(): # pragma: no cover (platform dependent)
return C.DEFAULT
def _sys_executable_matches(version):
def _sys_executable_matches(version: str) -> bool:
if version == 'python':
return True
elif not version.startswith('python'):
@ -102,7 +117,7 @@ def _sys_executable_matches(version):
return sys.version_info[:len(info)] == info
def norm_version(version):
def norm_version(version: str) -> str:
# first see if our current executable is appropriate
if _sys_executable_matches(version):
return sys.executable
@ -126,14 +141,25 @@ def norm_version(version):
return os.path.expanduser(version)
def py_interface(_dir, _make_venv):
def py_interface(
_dir: str,
_make_venv: Callable[[str, str], None],
) -> Tuple[
Callable[[Prefix, str], ContextManager[None]],
Callable[[Prefix, str], bool],
Callable[['Hook', Sequence[str], bool], Tuple[int, bytes]],
Callable[[Prefix, str, Sequence[str]], None],
]:
@contextlib.contextmanager
def in_env(prefix, language_version):
def in_env(
prefix: Prefix,
language_version: str,
) -> Generator[None, None, None]:
envdir = prefix.path(helpers.environment_dir(_dir, language_version))
with envcontext(get_env_patch(envdir)):
yield
def healthy(prefix, language_version):
def healthy(prefix: Prefix, language_version: str) -> bool:
with in_env(prefix, language_version):
retcode, _, _ = cmd_output_b(
'python', '-c',
@ -143,11 +169,19 @@ def py_interface(_dir, _make_venv):
)
return retcode == 0
def run_hook(hook, file_args, color):
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)
def install_environment(prefix, version, additional_dependencies):
def install_environment(
prefix: Prefix,
version: str,
additional_dependencies: Sequence[str],
) -> None:
additional_dependencies = tuple(additional_dependencies)
directory = helpers.environment_dir(_dir, version)
@ -166,7 +200,7 @@ def py_interface(_dir, _make_venv):
return in_env, healthy, run_hook, install_environment
def make_venv(envdir, python):
def make_venv(envdir: str, python: str) -> None:
env = dict(os.environ, VIRTUALENV_NO_DOWNLOAD='1')
cmd = (sys.executable, '-mvirtualenv', envdir, '-p', python)
cmd_output_b(*cmd, env=env, cwd='/')

View file

@ -5,15 +5,11 @@ from pre_commit.util import CalledProcessError
from pre_commit.util import cmd_output
from pre_commit.util import cmd_output_b
ENVIRONMENT_DIR = 'py_venv'
get_default_version = python.get_default_version
def get_default_version(): # pragma: no cover (version specific)
return python.get_default_version()
def orig_py_exe(exe): # pragma: no cover (platform specific)
def orig_py_exe(exe: str) -> str: # pragma: no cover (platform specific)
"""A -mvenv virtualenv made from a -mvirtualenv virtualenv installs
packages to the incorrect location. Attempt to find the _original_ exe
and invoke `-mvenv` from there.
@ -42,7 +38,7 @@ def orig_py_exe(exe): # pragma: no cover (platform specific)
return exe
def make_venv(envdir, python):
def make_venv(envdir: str, python: str) -> None:
cmd_output_b(orig_py_exe(python), '-mvenv', envdir, cwd='/')

View file

@ -2,23 +2,33 @@ import contextlib
import os.path
import shutil
import tarfile
from typing import Generator
from typing import Sequence
from typing import Tuple
from typing import TYPE_CHECKING
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.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
if TYPE_CHECKING:
from pre_comit.repository import Hook
ENVIRONMENT_DIR = 'rbenv'
get_default_version = helpers.basic_get_default_version
healthy = helpers.basic_healthy
def get_env_patch(venv, language_version): # pragma: windows no cover
def get_env_patch(
venv: str,
language_version: str,
) -> PatchesT: # pragma: windows no cover
patches: PatchesT = (
('GEM_HOME', os.path.join(venv, 'gems')),
('RBENV_ROOT', venv),
@ -36,8 +46,11 @@ def get_env_patch(venv, language_version): # pragma: windows no cover
return patches
@contextlib.contextmanager
def in_env(prefix, language_version): # pragma: windows no cover
@contextlib.contextmanager # pragma: windows no cover
def in_env(
prefix: Prefix,
language_version: str,
) -> Generator[None, None, None]:
envdir = prefix.path(
helpers.environment_dir(ENVIRONMENT_DIR, language_version),
)
@ -45,13 +58,16 @@ def in_env(prefix, language_version): # pragma: windows no cover
yield
def _extract_resource(filename, dest):
def _extract_resource(filename: str, dest: str) -> None:
with resource_bytesio(filename) as bio:
with tarfile.open(fileobj=bio) as tf:
tf.extractall(dest)
def _install_rbenv(prefix, version=C.DEFAULT): # pragma: windows no cover
def _install_rbenv(
prefix: Prefix,
version: str = C.DEFAULT,
) -> None: # pragma: windows no cover
directory = helpers.environment_dir(ENVIRONMENT_DIR, version)
_extract_resource('rbenv.tar.gz', prefix.path('.'))
@ -87,7 +103,10 @@ def _install_rbenv(prefix, version=C.DEFAULT): # pragma: windows no cover
activate_file.write(f'export RBENV_VERSION="{version}"\n')
def _install_ruby(prefix, version): # pragma: windows no cover
def _install_ruby(
prefix: Prefix,
version: str,
) -> None: # pragma: windows no cover
try:
helpers.run_setup_cmd(prefix, ('rbenv', 'download', version))
except CalledProcessError: # pragma: no cover (usually find with download)
@ -96,8 +115,8 @@ def _install_ruby(prefix, version): # pragma: windows no cover
def install_environment(
prefix, version, additional_dependencies,
): # pragma: windows no cover
prefix: Prefix, version: str, additional_dependencies: Sequence[str],
) -> None: # pragma: windows no cover
additional_dependencies = tuple(additional_dependencies)
directory = helpers.environment_dir(ENVIRONMENT_DIR, version)
with clean_path_on_failure(prefix.path(directory)):
@ -122,6 +141,10 @@ def install_environment(
)
def run_hook(hook, file_args, color): # pragma: windows no cover
def run_hook(
hook: 'Hook',
file_args: Sequence[str],
color: bool,
) -> Tuple[int, bytes]: # pragma: windows no cover
with in_env(hook.prefix, hook.language_version):
return helpers.run_xargs(hook, hook.cmd, file_args, color=color)

View file

@ -1,24 +1,31 @@
import contextlib
import os.path
from typing import Generator
from typing import Sequence
from typing import Set
from typing import Tuple
from typing import TYPE_CHECKING
import toml
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.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
if TYPE_CHECKING:
from pre_commit.repository import Hook
ENVIRONMENT_DIR = 'rustenv'
get_default_version = helpers.basic_get_default_version
healthy = helpers.basic_healthy
def get_env_patch(target_dir):
def get_env_patch(target_dir: str) -> PatchesT:
return (
(
'PATH',
@ -28,7 +35,7 @@ def get_env_patch(target_dir):
@contextlib.contextmanager
def in_env(prefix):
def in_env(prefix: Prefix) -> Generator[None, None, None]:
target_dir = prefix.path(
helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT),
)
@ -36,7 +43,10 @@ def in_env(prefix):
yield
def _add_dependencies(cargo_toml_path, additional_dependencies):
def _add_dependencies(
cargo_toml_path: str,
additional_dependencies: Set[str],
) -> None:
with open(cargo_toml_path, 'r+') as f:
cargo_toml = toml.load(f)
cargo_toml.setdefault('dependencies', {})
@ -48,7 +58,11 @@ def _add_dependencies(cargo_toml_path, additional_dependencies):
f.truncate()
def install_environment(prefix, version, additional_dependencies):
def install_environment(
prefix: Prefix,
version: str,
additional_dependencies: Sequence[str],
) -> None:
helpers.assert_version_default('rust', version)
directory = prefix.path(
helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT),
@ -82,13 +96,17 @@ def install_environment(prefix, version, additional_dependencies):
else:
packages_to_install.add((package,))
for package in packages_to_install:
for args in packages_to_install:
cmd_output_b(
'cargo', 'install', '--bins', '--root', directory, *package,
'cargo', 'install', '--bins', '--root', directory, *args,
cwd=prefix.prefix_dir,
)
def run_hook(hook, file_args, color):
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)

View file

@ -1,5 +1,11 @@
from typing import Sequence
from typing import Tuple
from typing import TYPE_CHECKING
from pre_commit.languages import helpers
if TYPE_CHECKING:
from pre_commit.repository import Hook
ENVIRONMENT_DIR = None
get_default_version = helpers.basic_get_default_version
@ -7,7 +13,11 @@ healthy = helpers.basic_healthy
install_environment = helpers.no_install
def run_hook(hook, file_args, color):
def run_hook(
hook: 'Hook',
file_args: Sequence[str],
color: bool,
) -> Tuple[int, bytes]:
cmd = hook.cmd
cmd = (hook.prefix.path(cmd[0]),) + cmd[1:]
return helpers.run_xargs(hook, cmd, file_args, color=color)

View file

@ -1,13 +1,22 @@
import contextlib
import os
from typing import Generator
from typing import Sequence
from typing import Tuple
from typing import TYPE_CHECKING
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.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
if TYPE_CHECKING:
from pre_commit.repository import Hook
ENVIRONMENT_DIR = 'swift_env'
get_default_version = helpers.basic_get_default_version
healthy = helpers.basic_healthy
@ -15,13 +24,13 @@ BUILD_DIR = '.build'
BUILD_CONFIG = 'release'
def get_env_patch(venv): # pragma: windows no cover
def get_env_patch(venv: str) -> PatchesT: # pragma: windows no cover
bin_path = os.path.join(venv, BUILD_DIR, BUILD_CONFIG)
return (('PATH', (bin_path, os.pathsep, Var('PATH'))),)
@contextlib.contextmanager
def in_env(prefix): # pragma: windows no cover
@contextlib.contextmanager # pragma: windows no cover
def in_env(prefix: Prefix) -> Generator[None, None, None]:
envdir = prefix.path(
helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT),
)
@ -30,8 +39,8 @@ def in_env(prefix): # pragma: windows no cover
def install_environment(
prefix, version, additional_dependencies,
): # pragma: windows no cover
prefix: Prefix, version: str, additional_dependencies: Sequence[str],
) -> None: # pragma: windows no cover
helpers.assert_version_default('swift', version)
helpers.assert_no_additional_deps('swift', additional_dependencies)
directory = prefix.path(
@ -49,6 +58,10 @@ def install_environment(
)
def run_hook(hook, file_args, color): # pragma: windows no cover
def run_hook(
hook: 'Hook',
file_args: Sequence[str],
color: bool,
) -> Tuple[int, bytes]: # pragma: windows no cover
with in_env(hook.prefix):
return helpers.run_xargs(hook, hook.cmd, file_args, color=color)

View file

@ -1,5 +1,12 @@
from typing import Sequence
from typing import Tuple
from typing import TYPE_CHECKING
from pre_commit.languages import helpers
if TYPE_CHECKING:
from pre_commit.repository import Hook
ENVIRONMENT_DIR = None
get_default_version = helpers.basic_get_default_version
@ -7,5 +14,9 @@ healthy = helpers.basic_healthy
install_environment = helpers.no_install
def run_hook(hook, file_args, color):
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)