mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-02-17 08:14:42 +04:00
Add types to pre-commit
This commit is contained in:
parent
fa536a8693
commit
327ed924a3
62 changed files with 911 additions and 411 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 '
|
||||
|
|
|
|||
|
|
@ -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='/')
|
||||
|
|
|
|||
|
|
@ -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='/')
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue