init
This commit is contained in:
commit
38355d2442
9083 changed files with 1225834 additions and 0 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,70 @@
|
|||
from typing import Callable
|
||||
from typing import NamedTuple
|
||||
from typing import Optional
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
from pre_commit.hook import Hook
|
||||
from pre_commit.languages import conda
|
||||
from pre_commit.languages import coursier
|
||||
from pre_commit.languages import dart
|
||||
from pre_commit.languages import docker
|
||||
from pre_commit.languages import docker_image
|
||||
from pre_commit.languages import dotnet
|
||||
from pre_commit.languages import fail
|
||||
from pre_commit.languages import golang
|
||||
from pre_commit.languages import lua
|
||||
from pre_commit.languages import node
|
||||
from pre_commit.languages import perl
|
||||
from pre_commit.languages import pygrep
|
||||
from pre_commit.languages import python
|
||||
from pre_commit.languages import r
|
||||
from pre_commit.languages import ruby
|
||||
from pre_commit.languages import rust
|
||||
from pre_commit.languages import script
|
||||
from pre_commit.languages import swift
|
||||
from pre_commit.languages import system
|
||||
from pre_commit.prefix import Prefix
|
||||
|
||||
|
||||
class Language(NamedTuple):
|
||||
name: str
|
||||
# Use `None` for no installation / environment
|
||||
ENVIRONMENT_DIR: Optional[str]
|
||||
# return a value to replace `'default` for `language_version`
|
||||
get_default_version: Callable[[], str]
|
||||
# return whether the environment is healthy (or should be rebuilt)
|
||||
healthy: Callable[[Prefix, str], bool]
|
||||
# install a repository for the given language and language_version
|
||||
install_environment: Callable[[Prefix, str, Sequence[str]], None]
|
||||
# execute a hook and return the exit code and output
|
||||
run_hook: 'Callable[[Hook, Sequence[str], 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, healthy=conda.healthy, 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, healthy=coursier.healthy, 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, healthy=dart.healthy, 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, healthy=docker.healthy, 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, healthy=docker_image.healthy, 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, healthy=dotnet.healthy, 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, healthy=fail.healthy, 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, healthy=golang.healthy, 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, healthy=lua.healthy, 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, healthy=node.healthy, 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, healthy=perl.healthy, install_environment=perl.install_environment, run_hook=perl.run_hook), # noqa: E501
|
||||
'pygrep': Language(name='pygrep', ENVIRONMENT_DIR=pygrep.ENVIRONMENT_DIR, get_default_version=pygrep.get_default_version, healthy=pygrep.healthy, install_environment=pygrep.install_environment, run_hook=pygrep.run_hook), # noqa: E501
|
||||
'python': Language(name='python', ENVIRONMENT_DIR=python.ENVIRONMENT_DIR, get_default_version=python.get_default_version, healthy=python.healthy, install_environment=python.install_environment, run_hook=python.run_hook), # noqa: E501
|
||||
'r': Language(name='r', ENVIRONMENT_DIR=r.ENVIRONMENT_DIR, get_default_version=r.get_default_version, healthy=r.healthy, install_environment=r.install_environment, run_hook=r.run_hook), # noqa: E501
|
||||
'ruby': Language(name='ruby', ENVIRONMENT_DIR=ruby.ENVIRONMENT_DIR, get_default_version=ruby.get_default_version, healthy=ruby.healthy, install_environment=ruby.install_environment, run_hook=ruby.run_hook), # noqa: E501
|
||||
'rust': Language(name='rust', ENVIRONMENT_DIR=rust.ENVIRONMENT_DIR, get_default_version=rust.get_default_version, healthy=rust.healthy, install_environment=rust.install_environment, run_hook=rust.run_hook), # noqa: E501
|
||||
'script': Language(name='script', ENVIRONMENT_DIR=script.ENVIRONMENT_DIR, get_default_version=script.get_default_version, healthy=script.healthy, install_environment=script.install_environment, run_hook=script.run_hook), # noqa: E501
|
||||
'swift': Language(name='swift', ENVIRONMENT_DIR=swift.ENVIRONMENT_DIR, get_default_version=swift.get_default_version, healthy=swift.healthy, 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, healthy=system.healthy, install_environment=system.install_environment, run_hook=system.run_hook), # noqa: E501
|
||||
# END GENERATED
|
||||
}
|
||||
# TODO: fully deprecate `python_venv`
|
||||
languages['python_venv'] = languages['python']
|
||||
all_languages = sorted(languages)
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
import contextlib
|
||||
import os
|
||||
from typing import Generator
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
from pre_commit.envcontext import envcontext
|
||||
from pre_commit.envcontext import PatchesT
|
||||
from pre_commit.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
|
||||
healthy = helpers.basic_healthy
|
||||
|
||||
|
||||
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
|
||||
# seems to be used for python.exe.
|
||||
path: SubstitutionT = (os.path.join(env, 'bin'), os.pathsep, Var('PATH'))
|
||||
if os.name == 'nt': # pragma: no cover (platform specific)
|
||||
path = (env, os.pathsep, *path)
|
||||
path = (os.path.join(env, 'Scripts'), os.pathsep, *path)
|
||||
path = (os.path.join(env, 'Library', 'bin'), os.pathsep, *path)
|
||||
|
||||
return (
|
||||
('PYTHONHOME', UNSET),
|
||||
('VIRTUAL_ENV', UNSET),
|
||||
('CONDA_PREFIX', env),
|
||||
('PATH', path),
|
||||
)
|
||||
|
||||
|
||||
@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)
|
||||
with envcontext(get_env_patch(envdir)):
|
||||
yield
|
||||
|
||||
|
||||
def _conda_exe() -> str:
|
||||
if os.environ.get('PRE_COMMIT_USE_MICROMAMBA'):
|
||||
return 'micromamba'
|
||||
elif os.environ.get('PRE_COMMIT_USE_MAMBA'):
|
||||
return 'mamba'
|
||||
else:
|
||||
return 'conda'
|
||||
|
||||
|
||||
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)
|
||||
|
||||
conda_exe = _conda_exe()
|
||||
|
||||
env_dir = prefix.path(directory)
|
||||
with clean_path_on_failure(env_dir):
|
||||
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, '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)
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
import contextlib
|
||||
import os
|
||||
from typing import Generator
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
from pre_commit.envcontext import envcontext
|
||||
from pre_commit.envcontext import PatchesT
|
||||
from pre_commit.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 = 'coursier'
|
||||
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
healthy = helpers.basic_healthy
|
||||
|
||||
|
||||
def install_environment(
|
||||
prefix: Prefix,
|
||||
version: str,
|
||||
additional_dependencies: Sequence[str],
|
||||
) -> None: # pragma: win32 no cover
|
||||
helpers.assert_version_default('coursier', version)
|
||||
helpers.assert_no_additional_deps('coursier', additional_dependencies)
|
||||
|
||||
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,
|
||||
(
|
||||
'cs',
|
||||
'install',
|
||||
'--default-channels=false',
|
||||
f'--channel={channel}',
|
||||
app,
|
||||
f'--dir={envdir}',
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def get_env_patch(target_dir: str) -> PatchesT: # pragma: win32 no cover
|
||||
return (
|
||||
('PATH', (target_dir, os.pathsep, Var('PATH'))),
|
||||
)
|
||||
|
||||
|
||||
@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)):
|
||||
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)
|
||||
109
.venv/lib/python3.8/site-packages/pre_commit/languages/dart.py
Normal file
109
.venv/lib/python3.8/site-packages/pre_commit/languages/dart.py
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
import contextlib
|
||||
import os.path
|
||||
import shutil
|
||||
import tempfile
|
||||
from typing import Generator
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
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
|
||||
|
||||
ENVIRONMENT_DIR = 'dartenv'
|
||||
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
healthy = helpers.basic_healthy
|
||||
|
||||
|
||||
def get_env_patch(venv: str) -> PatchesT:
|
||||
return (
|
||||
('PATH', (os.path.join(venv, 'bin'), os.pathsep, Var('PATH'))),
|
||||
)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_env(prefix: Prefix) -> Generator[None, None, None]:
|
||||
directory = helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT)
|
||||
envdir = prefix.path(directory)
|
||||
with envcontext(get_env_patch(envdir)):
|
||||
yield
|
||||
|
||||
|
||||
def install_environment(
|
||||
prefix: Prefix,
|
||||
version: str,
|
||||
additional_dependencies: Sequence[str],
|
||||
) -> None:
|
||||
helpers.assert_version_default('dart', version)
|
||||
|
||||
envdir = prefix.path(helpers.environment_dir(ENVIRONMENT_DIR, version))
|
||||
bin_dir = os.path.join(envdir, 'bin')
|
||||
|
||||
def _install_dir(prefix_p: Prefix, pub_cache: str) -> None:
|
||||
dart_env = {**os.environ, 'PUB_CACHE': pub_cache}
|
||||
|
||||
with open(prefix_p.path('pubspec.yaml')) as f:
|
||||
pubspec_contents = yaml_load(f)
|
||||
|
||||
helpers.run_setup_cmd(prefix_p, ('dart', 'pub', 'get'), env=dart_env)
|
||||
|
||||
for executable in pubspec_contents['executables']:
|
||||
helpers.run_setup_cmd(
|
||||
prefix_p,
|
||||
(
|
||||
'dart', 'compile', 'exe',
|
||||
'--output', os.path.join(bin_dir, win_exe(executable)),
|
||||
prefix_p.path('bin', f'{executable}.dart'),
|
||||
),
|
||||
env=dart_env,
|
||||
)
|
||||
|
||||
with clean_path_on_failure(envdir):
|
||||
os.makedirs(bin_dir)
|
||||
|
||||
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,)
|
||||
|
||||
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}',
|
||||
)
|
||||
|
||||
|
||||
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)
|
||||
141
.venv/lib/python3.8/site-packages/pre_commit/languages/docker.py
Normal file
141
.venv/lib/python3.8/site-packages/pre_commit/languages/docker.py
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
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
|
||||
healthy = helpers.basic_healthy
|
||||
|
||||
|
||||
def _is_in_docker() -> bool:
|
||||
try:
|
||||
with open('/proc/1/cgroup', 'rb') as f:
|
||||
return b'docker' in f.read()
|
||||
except FileNotFoundError:
|
||||
return False
|
||||
|
||||
|
||||
def _get_container_id() -> str:
|
||||
# It's assumed that we already check /proc/1/cgroup in _is_in_docker. The
|
||||
# cpuset cgroup controller existed since cgroups were introduced so this
|
||||
# way of getting the container ID is pretty reliable.
|
||||
with open('/proc/1/cgroup', 'rb') as f:
|
||||
for line in f.readlines():
|
||||
if line.split(b':')[1] == b'cpuset':
|
||||
return os.path.basename(line.split(b':')[2]).strip().decode()
|
||||
raise RuntimeError('Failed to find the container ID in /proc/1/cgroup.')
|
||||
|
||||
|
||||
def _get_docker_path(path: str) -> str:
|
||||
if not _is_in_docker():
|
||||
return path
|
||||
|
||||
container_id = _get_container_id()
|
||||
|
||||
try:
|
||||
_, out, _ = cmd_output_b('docker', 'inspect', container_id)
|
||||
except CalledProcessError:
|
||||
# self-container was not visible from here (perhaps docker-in-docker)
|
||||
return path
|
||||
|
||||
container, = json.loads(out)
|
||||
for mount in container['Mounts']:
|
||||
src_path = mount['Source']
|
||||
to_path = mount['Destination']
|
||||
if os.path.commonpath((path, to_path)) == to_path:
|
||||
# So there is something in common,
|
||||
# and we can proceed remapping it
|
||||
return path.replace(to_path, src_path)
|
||||
# we're in Docker, but the path is not mounted, cannot really do anything,
|
||||
# so fall back to original path
|
||||
return path
|
||||
|
||||
|
||||
def md5(s: str) -> str: # pragma: win32 no cover
|
||||
return hashlib.md5(s.encode()).hexdigest()
|
||||
|
||||
|
||||
def docker_tag(prefix: Prefix) -> str: # pragma: win32 no cover
|
||||
md5sum = md5(os.path.basename(prefix.prefix_dir)).lower()
|
||||
return f'pre-commit-{md5sum}'
|
||||
|
||||
|
||||
def build_docker_image(
|
||||
prefix: Prefix,
|
||||
*,
|
||||
pull: bool,
|
||||
) -> None: # pragma: win32 no cover
|
||||
cmd: Tuple[str, ...] = (
|
||||
'docker', 'build',
|
||||
'--tag', docker_tag(prefix),
|
||||
'--label', PRE_COMMIT_LABEL,
|
||||
)
|
||||
if pull:
|
||||
cmd += ('--pull',)
|
||||
# This must come last for old versions of docker. See #477
|
||||
cmd += ('.',)
|
||||
helpers.run_setup_cmd(prefix, cmd)
|
||||
|
||||
|
||||
def install_environment(
|
||||
prefix: Prefix, version: str, additional_dependencies: Sequence[str],
|
||||
) -> None: # pragma: win32 no cover
|
||||
helpers.assert_version_default('docker', version)
|
||||
helpers.assert_no_additional_deps('docker', additional_dependencies)
|
||||
|
||||
directory = prefix.path(
|
||||
helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT),
|
||||
)
|
||||
|
||||
# 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)
|
||||
|
||||
|
||||
def get_docker_user() -> Tuple[str, ...]: # pragma: win32 no cover
|
||||
try:
|
||||
return ('-u', f'{os.getuid()}:{os.getgid()}')
|
||||
except AttributeError:
|
||||
return ()
|
||||
|
||||
|
||||
def docker_cmd() -> Tuple[str, ...]: # pragma: win32 no cover
|
||||
return (
|
||||
'docker', 'run',
|
||||
'--rm',
|
||||
*get_docker_user(),
|
||||
# https://docs.docker.com/engine/reference/commandline/run/#mount-volumes-from-container-volumes-from
|
||||
# The `Z` option tells Docker to label the content with a private
|
||||
# unshared label. Only the current container can use a private volume.
|
||||
'-v', f'{_get_docker_path(os.getcwd())}:/src:rw,Z',
|
||||
'--workdir', '/src',
|
||||
)
|
||||
|
||||
|
||||
def run_hook(
|
||||
hook: Hook,
|
||||
file_args: Sequence[str],
|
||||
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)
|
||||
|
||||
entry_exe, *cmd_rest = hook.cmd
|
||||
|
||||
entry_tag = ('--entrypoint', entry_exe, docker_tag(hook.prefix))
|
||||
cmd = (*docker_cmd(), *entry_tag, *cmd_rest)
|
||||
return helpers.run_xargs(hook, cmd, file_args, color=color)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
from pre_commit.hook import Hook
|
||||
from pre_commit.languages import helpers
|
||||
from pre_commit.languages.docker import docker_cmd
|
||||
|
||||
ENVIRONMENT_DIR = None
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
healthy = helpers.basic_healthy
|
||||
install_environment = helpers.no_install
|
||||
|
||||
|
||||
def run_hook(
|
||||
hook: Hook,
|
||||
file_args: Sequence[str],
|
||||
color: bool,
|
||||
) -> Tuple[int, bytes]: # pragma: win32 no cover
|
||||
cmd = docker_cmd() + hook.cmd
|
||||
return helpers.run_xargs(hook, cmd, file_args, color=color)
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
import contextlib
|
||||
import os.path
|
||||
from typing import Generator
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
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
|
||||
healthy = helpers.basic_healthy
|
||||
|
||||
|
||||
def get_env_patch(venv: str) -> PatchesT:
|
||||
return (
|
||||
('PATH', (os.path.join(venv, BIN_DIR), os.pathsep, Var('PATH'))),
|
||||
)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_env(prefix: Prefix) -> Generator[None, None, None]:
|
||||
directory = helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT)
|
||||
envdir = prefix.path(directory)
|
||||
with envcontext(get_env_patch(envdir)):
|
||||
yield
|
||||
|
||||
|
||||
def install_environment(
|
||||
prefix: Prefix,
|
||||
version: str,
|
||||
additional_dependencies: Sequence[str],
|
||||
) -> None:
|
||||
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'
|
||||
|
||||
# Build & pack nupkg file
|
||||
helpers.run_setup_cmd(
|
||||
prefix,
|
||||
(
|
||||
'dotnet', 'pack',
|
||||
'--configuration', 'Release',
|
||||
'--output', build_dir,
|
||||
),
|
||||
)
|
||||
|
||||
# Determine tool from the packaged file <tool_name>.<version>.nupkg
|
||||
build_outputs = os.listdir(os.path.join(prefix.prefix_dir, build_dir))
|
||||
if len(build_outputs) != 1:
|
||||
raise NotImplementedError(
|
||||
f"Can't handle multiple build outputs. Got {build_outputs}",
|
||||
)
|
||||
tool_name = build_outputs[0].split('.')[0]
|
||||
|
||||
# Install to bin dir
|
||||
helpers.run_setup_cmd(
|
||||
prefix,
|
||||
(
|
||||
'dotnet', 'tool', 'install',
|
||||
'--tool-path', os.path.join(envdir, BIN_DIR),
|
||||
'--add-source', build_dir,
|
||||
tool_name,
|
||||
),
|
||||
)
|
||||
|
||||
# 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)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
from pre_commit.hook import Hook
|
||||
from pre_commit.languages import helpers
|
||||
|
||||
ENVIRONMENT_DIR = None
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
healthy = helpers.basic_healthy
|
||||
install_environment = helpers.no_install
|
||||
|
||||
|
||||
def run_hook(
|
||||
hook: Hook,
|
||||
file_args: Sequence[str],
|
||||
color: bool,
|
||||
) -> Tuple[int, bytes]:
|
||||
out = f'{hook.entry}\n\n'.encode()
|
||||
out += b'\n'.join(f.encode() for f in file_args) + b'\n'
|
||||
return 1, out
|
||||
100
.venv/lib/python3.8/site-packages/pre_commit/languages/golang.py
Normal file
100
.venv/lib/python3.8/site-packages/pre_commit/languages/golang.py
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
import contextlib
|
||||
import os.path
|
||||
import sys
|
||||
from typing import Generator
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
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
|
||||
healthy = helpers.basic_healthy
|
||||
|
||||
|
||||
def get_env_patch(venv: str) -> PatchesT:
|
||||
return (
|
||||
('PATH', (os.path.join(venv, 'bin'), os.pathsep, Var('PATH'))),
|
||||
)
|
||||
|
||||
|
||||
@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)):
|
||||
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),
|
||||
)
|
||||
|
||||
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))
|
||||
|
||||
# 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', 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)
|
||||
|
||||
|
||||
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)
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
import multiprocessing
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
from typing import Any
|
||||
from typing import List
|
||||
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 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
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import NoReturn
|
||||
|
||||
FIXED_RANDOM_SEED = 1542676187
|
||||
|
||||
SHIMS_RE = re.compile(r'[/\\]shims[/\\]')
|
||||
|
||||
|
||||
def exe_exists(exe: str) -> bool:
|
||||
found = parse_shebang.find_executable(exe)
|
||||
if found is None: # exe exists
|
||||
return False
|
||||
|
||||
homedir = os.path.expanduser('~')
|
||||
try:
|
||||
common: Optional[str] = os.path.commonpath((found, homedir))
|
||||
except ValueError: # on windows, different drives raises ValueError
|
||||
common = None
|
||||
|
||||
return (
|
||||
# it is not in a /shims/ directory
|
||||
not SHIMS_RE.search(found) and
|
||||
(
|
||||
# the homedir is / (docker, service user, etc.)
|
||||
os.path.dirname(homedir) == homedir or
|
||||
# the exe is not contained in the home directory
|
||||
common != homedir
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
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: Optional[str], language_version: str) -> Optional[str]:
|
||||
if d is None:
|
||||
return None
|
||||
else:
|
||||
return f'{d}-{language_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: str,
|
||||
additional_deps: Sequence[str],
|
||||
) -> None:
|
||||
if additional_deps:
|
||||
raise AssertionError(
|
||||
f'For now, pre-commit does not support '
|
||||
f'additional_dependencies for {lang}',
|
||||
)
|
||||
|
||||
|
||||
def basic_get_default_version() -> str:
|
||||
return C.DEFAULT
|
||||
|
||||
|
||||
def basic_healthy(prefix: Prefix, language_version: str) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def no_install(
|
||||
prefix: Prefix,
|
||||
version: str,
|
||||
additional_dependencies: Sequence[str],
|
||||
) -> 'NoReturn':
|
||||
raise AssertionError('This type is not installable')
|
||||
|
||||
|
||||
def target_concurrency(hook: Hook) -> int:
|
||||
if hook.require_serial or '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.
|
||||
if 'TRAVIS' in os.environ:
|
||||
return 2
|
||||
else:
|
||||
try:
|
||||
return multiprocessing.cpu_count()
|
||||
except NotImplementedError:
|
||||
return 1
|
||||
|
||||
|
||||
def _shuffled(seq: Sequence[str]) -> List[str]:
|
||||
"""Deterministically shuffle"""
|
||||
fixed_random = random.Random()
|
||||
fixed_random.seed(FIXED_RANDOM_SEED, version=1)
|
||||
|
||||
seq = list(seq)
|
||||
fixed_random.shuffle(seq)
|
||||
return seq
|
||||
|
||||
|
||||
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)
|
||||
kwargs['target_concurrency'] = target_concurrency(hook)
|
||||
return xargs(cmd, file_args, **kwargs)
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
import contextlib
|
||||
import os
|
||||
import sys
|
||||
from typing import Generator
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
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
|
||||
healthy = helpers.basic_healthy
|
||||
|
||||
|
||||
def _get_lua_version() -> str: # pragma: win32 no cover
|
||||
"""Get the Lua version used in file paths."""
|
||||
_, stdout, _ = cmd_output('luarocks', 'config', '--lua-ver')
|
||||
return stdout.strip()
|
||||
|
||||
|
||||
def get_env_patch(d: str) -> PatchesT: # pragma: win32 no cover
|
||||
version = _get_lua_version()
|
||||
so_ext = 'dll' if sys.platform == 'win32' else 'so'
|
||||
return (
|
||||
('PATH', (os.path.join(d, 'bin'), os.pathsep, Var('PATH'))),
|
||||
(
|
||||
'LUA_PATH', (
|
||||
os.path.join(d, 'share', 'lua', version, '?.lua;'),
|
||||
os.path.join(d, 'share', 'lua', version, '?', 'init.lua;;'),
|
||||
),
|
||||
),
|
||||
(
|
||||
'LUA_CPATH',
|
||||
(os.path.join(d, 'lib', 'lua', version, f'?.{so_ext};;'),),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
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))):
|
||||
yield
|
||||
|
||||
|
||||
def install_environment(
|
||||
prefix: Prefix,
|
||||
version: str,
|
||||
additional_dependencies: Sequence[str],
|
||||
) -> 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)
|
||||
|
||||
# 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)
|
||||
127
.venv/lib/python3.8/site-packages/pre_commit/languages/node.py
Normal file
127
.venv/lib/python3.8/site-packages/pre_commit/languages/node.py
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
import contextlib
|
||||
import functools
|
||||
import os
|
||||
import sys
|
||||
from typing import Generator
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
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.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'
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=1)
|
||||
def get_default_version() -> str:
|
||||
# nodeenv does not yet support `-n system` on windows
|
||||
if sys.platform == 'win32':
|
||||
return C.DEFAULT
|
||||
# if node is already installed, we can save a bunch of setup time by
|
||||
# using the installed version
|
||||
elif all(helpers.exe_exists(exe) for exe in ('node', 'npm')):
|
||||
return 'system'
|
||||
else:
|
||||
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)
|
||||
install_prefix = fr'{win_venv.strip()}\bin'
|
||||
lib_dir = 'lib'
|
||||
elif sys.platform == 'win32': # pragma: no cover
|
||||
install_prefix = bin_dir(venv)
|
||||
lib_dir = 'Scripts'
|
||||
else: # pragma: win32 no cover
|
||||
install_prefix = venv
|
||||
lib_dir = 'lib'
|
||||
return (
|
||||
('NODE_VIRTUAL_ENV', venv),
|
||||
('NPM_CONFIG_PREFIX', install_prefix),
|
||||
('npm_config_prefix', install_prefix),
|
||||
('NPM_CONFIG_USERCONFIG', UNSET),
|
||||
('npm_config_userconfig', UNSET),
|
||||
('NODE_PATH', os.path.join(venv, lib_dir, 'node_modules')),
|
||||
('PATH', (bin_dir(venv), os.pathsep, Var('PATH'))),
|
||||
)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_env(
|
||||
prefix: Prefix,
|
||||
language_version: str,
|
||||
) -> Generator[None, None, None]:
|
||||
with envcontext(get_env_patch(_envdir(prefix, language_version))):
|
||||
yield
|
||||
|
||||
|
||||
def healthy(prefix: Prefix, language_version: str) -> bool:
|
||||
with in_env(prefix, language_version):
|
||||
retcode, _, _ = cmd_output_b('node', '--version', retcode=None)
|
||||
return retcode == 0
|
||||
|
||||
|
||||
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)
|
||||
|
||||
# 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)
|
||||
|
||||
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)
|
||||
|
||||
_, 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)
|
||||
|
||||
# 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)
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
import contextlib
|
||||
import os
|
||||
import shlex
|
||||
from typing import Generator
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
from pre_commit.envcontext import envcontext
|
||||
from pre_commit.envcontext import PatchesT
|
||||
from pre_commit.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
|
||||
healthy = helpers.basic_healthy
|
||||
|
||||
|
||||
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:
|
||||
return (
|
||||
('PATH', (os.path.join(venv, 'bin'), os.pathsep, Var('PATH'))),
|
||||
('PERL5LIB', os.path.join(venv, 'lib', 'perl5')),
|
||||
('PERL_MB_OPT', f'--install_base {shlex.quote(venv)}'),
|
||||
(
|
||||
'PERL_MM_OPT', (
|
||||
f'INSTALL_BASE={shlex.quote(venv)} '
|
||||
f'INSTALLSITEMAN1DIR=none INSTALLSITEMAN3DIR=none'
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_env(
|
||||
prefix: Prefix,
|
||||
language_version: str,
|
||||
) -> Generator[None, None, None]:
|
||||
with envcontext(get_env_patch(_envdir(prefix, language_version))):
|
||||
yield
|
||||
|
||||
|
||||
def install_environment(
|
||||
prefix: Prefix, version: str, additional_dependencies: Sequence[str],
|
||||
) -> 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)
|
||||
127
.venv/lib/python3.8/site-packages/pre_commit/languages/pygrep.py
Normal file
127
.venv/lib/python3.8/site-packages/pre_commit/languages/pygrep.py
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
import argparse
|
||||
import re
|
||||
import sys
|
||||
from typing import NamedTuple
|
||||
from typing import Optional
|
||||
from typing import Pattern
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
from pre_commit import output
|
||||
from pre_commit.hook import Hook
|
||||
from pre_commit.languages import helpers
|
||||
from pre_commit.xargs import xargs
|
||||
|
||||
ENVIRONMENT_DIR = None
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
healthy = helpers.basic_healthy
|
||||
install_environment = helpers.no_install
|
||||
|
||||
|
||||
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):
|
||||
if pattern.search(line):
|
||||
retv = 1
|
||||
output.write(f'{filename}:{line_no}:')
|
||||
output.write_line_b(line.rstrip(b'\r\n'))
|
||||
return retv
|
||||
|
||||
|
||||
def _process_filename_at_once(pattern: Pattern[bytes], filename: str) -> int:
|
||||
retv = 0
|
||||
with open(filename, 'rb') as f:
|
||||
contents = f.read()
|
||||
match = pattern.search(contents)
|
||||
if match:
|
||||
retv = 1
|
||||
line_no = contents[:match.start()].count(b'\n')
|
||||
output.write(f'{filename}:{line_no + 1}:')
|
||||
|
||||
matched_lines = match[0].split(b'\n')
|
||||
matched_lines[0] = contents.split(b'\n')[line_no]
|
||||
|
||||
output.write_line_b(b'\n'.join(matched_lines))
|
||||
return retv
|
||||
|
||||
|
||||
def _process_filename_by_line_negated(
|
||||
pattern: Pattern[bytes],
|
||||
filename: str,
|
||||
) -> int:
|
||||
with open(filename, 'rb') as f:
|
||||
for line in f:
|
||||
if pattern.search(line):
|
||||
return 0
|
||||
else:
|
||||
output.write_line(filename)
|
||||
return 1
|
||||
|
||||
|
||||
def _process_filename_at_once_negated(
|
||||
pattern: Pattern[bytes],
|
||||
filename: str,
|
||||
) -> int:
|
||||
with open(filename, 'rb') as f:
|
||||
contents = f.read()
|
||||
match = pattern.search(contents)
|
||||
if match:
|
||||
return 0
|
||||
else:
|
||||
output.write_line(filename)
|
||||
return 1
|
||||
|
||||
|
||||
class Choice(NamedTuple):
|
||||
multiline: bool
|
||||
negate: bool
|
||||
|
||||
|
||||
FNS = {
|
||||
Choice(multiline=True, negate=True): _process_filename_at_once_negated,
|
||||
Choice(multiline=True, negate=False): _process_filename_at_once,
|
||||
Choice(multiline=False, negate=True): _process_filename_by_line_negated,
|
||||
Choice(multiline=False, negate=False): _process_filename_by_line,
|
||||
}
|
||||
|
||||
|
||||
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: Optional[Sequence[str]] = None) -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description=(
|
||||
'grep-like finder using python regexes. Unlike grep, this tool '
|
||||
'returns nonzero when it finds a match and zero otherwise. The '
|
||||
'idea here being that matches are "problems".'
|
||||
),
|
||||
)
|
||||
parser.add_argument('-i', '--ignore-case', action='store_true')
|
||||
parser.add_argument('--multiline', action='store_true')
|
||||
parser.add_argument('--negate', action='store_true')
|
||||
parser.add_argument('pattern', help='python regex pattern.')
|
||||
parser.add_argument('filenames', nargs='*')
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
flags = re.IGNORECASE if args.ignore_case else 0
|
||||
if args.multiline:
|
||||
flags |= re.MULTILINE | re.DOTALL
|
||||
|
||||
pattern = re.compile(args.pattern.encode(), flags)
|
||||
|
||||
retv = 0
|
||||
process_fn = FNS[Choice(multiline=args.multiline, negate=args.negate)]
|
||||
for filename in args.filenames:
|
||||
retv |= process_fn(pattern, filename)
|
||||
return retv
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
214
.venv/lib/python3.8/site-packages/pre_commit/languages/python.py
Normal file
214
.venv/lib/python3.8/site-packages/pre_commit/languages/python.py
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
import contextlib
|
||||
import functools
|
||||
import os
|
||||
import sys
|
||||
from typing import Dict
|
||||
from typing import Generator
|
||||
from typing import Optional
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
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.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'
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=None)
|
||||
def _version_info(exe: str) -> str:
|
||||
prog = 'import sys;print(".".join(str(p) for p in sys.version_info))'
|
||||
try:
|
||||
return cmd_output(exe, '-S', '-c', prog)[1].strip()
|
||||
except CalledProcessError:
|
||||
return f'<<error retrieving version from {exe}>>'
|
||||
|
||||
|
||||
def _read_pyvenv_cfg(filename: str) -> Dict[str, str]:
|
||||
ret = {}
|
||||
with open(filename, encoding='UTF-8') as f:
|
||||
for line in f:
|
||||
try:
|
||||
k, v = line.split('=')
|
||||
except ValueError: # blank line / comment / etc.
|
||||
continue
|
||||
else:
|
||||
ret[k.strip()] = v.strip()
|
||||
return ret
|
||||
|
||||
|
||||
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: str) -> PatchesT:
|
||||
return (
|
||||
('PIP_DISABLE_PIP_VERSION_CHECK', '1'),
|
||||
('PYTHONHOME', UNSET),
|
||||
('VIRTUAL_ENV', venv),
|
||||
('PATH', (bin_dir(venv), os.pathsep, Var('PATH'))),
|
||||
)
|
||||
|
||||
|
||||
def _find_by_py_launcher(
|
||||
version: str,
|
||||
) -> Optional[str]: # pragma: no cover (windows only)
|
||||
if version.startswith('python'):
|
||||
num = version[len('python'):]
|
||||
cmd = ('py', f'-{num}', '-c', 'import sys; print(sys.executable)')
|
||||
env = dict(os.environ, PYTHONIOENCODING='UTF-8')
|
||||
try:
|
||||
return cmd_output(*cmd, env=env)[1].strip()
|
||||
except CalledProcessError:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
def _find_by_sys_executable() -> Optional[str]:
|
||||
def _norm(path: str) -> Optional[str]:
|
||||
_, exe = os.path.split(path.lower())
|
||||
exe, _, _ = exe.partition('.exe')
|
||||
if exe not in {'python', 'pythonw'} and find_executable(exe):
|
||||
return exe
|
||||
return None
|
||||
|
||||
# On linux, I see these common sys.executables:
|
||||
#
|
||||
# system `python`: /usr/bin/python -> python2.7
|
||||
# system `python2`: /usr/bin/python2 -> python2.7
|
||||
# virtualenv v: v/bin/python (will not return from this loop)
|
||||
# virtualenv v -ppython2: v/bin/python -> python2
|
||||
# virtualenv v -ppython2.7: v/bin/python -> python2.7
|
||||
# virtualenv v -ppypy: v/bin/python -> v/bin/pypy
|
||||
for path in (sys.executable, os.path.realpath(sys.executable)):
|
||||
exe = _norm(path)
|
||||
if exe:
|
||||
return exe
|
||||
return None
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=1)
|
||||
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:
|
||||
return exe
|
||||
|
||||
# Next try the `pythonX.X` executable
|
||||
exe = f'python{sys.version_info[0]}.{sys.version_info[1]}'
|
||||
if find_executable(exe):
|
||||
return exe
|
||||
|
||||
if _find_by_py_launcher(exe):
|
||||
return exe
|
||||
|
||||
# We tried!
|
||||
return C.DEFAULT
|
||||
|
||||
|
||||
def _sys_executable_matches(version: str) -> bool:
|
||||
if version == 'python':
|
||||
return True
|
||||
elif not version.startswith('python'):
|
||||
return False
|
||||
|
||||
try:
|
||||
info = tuple(int(p) for p in version[len('python'):].split('.'))
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
return sys.version_info[:len(info)] == info
|
||||
|
||||
|
||||
def norm_version(version: str) -> Optional[str]:
|
||||
if version == C.DEFAULT: # use virtualenv's default
|
||||
return None
|
||||
elif _sys_executable_matches(version): # virtualenv defaults to our exe
|
||||
return None
|
||||
|
||||
if os.name == 'nt': # pragma: no cover (windows)
|
||||
version_exec = _find_by_py_launcher(version)
|
||||
if version_exec:
|
||||
return version_exec
|
||||
|
||||
# Try looking up by name
|
||||
version_exec = find_executable(version)
|
||||
if version_exec and version_exec != version:
|
||||
return version_exec
|
||||
|
||||
# Otherwise assume it is a path
|
||||
return os.path.expanduser(version)
|
||||
|
||||
|
||||
@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)
|
||||
with envcontext(get_env_patch(envdir)):
|
||||
yield
|
||||
|
||||
|
||||
def healthy(prefix: Prefix, language_version: str) -> bool:
|
||||
directory = helpers.environment_dir(ENVIRONMENT_DIR, language_version)
|
||||
envdir = prefix.path(directory)
|
||||
pyvenv_cfg = os.path.join(envdir, 'pyvenv.cfg')
|
||||
|
||||
# created with "old" virtualenv
|
||||
if not os.path.exists(pyvenv_cfg):
|
||||
return False
|
||||
|
||||
exe_name = win_exe('python')
|
||||
py_exe = prefix.path(bin_dir(envdir), exe_name)
|
||||
cfg = _read_pyvenv_cfg(pyvenv_cfg)
|
||||
|
||||
return (
|
||||
'version_info' in cfg and
|
||||
# always use uncached lookup here in case we replaced an unhealthy env
|
||||
_version_info.__wrapped__(py_exe) == cfg['version_info'] and (
|
||||
'base-executable' not in cfg or
|
||||
_version_info(cfg['base-executable']) == cfg['version_info']
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def install_environment(
|
||||
prefix: Prefix,
|
||||
version: str,
|
||||
additional_dependencies: Sequence[str],
|
||||
) -> None:
|
||||
envdir = prefix.path(helpers.environment_dir(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)
|
||||
155
.venv/lib/python3.8/site-packages/pre_commit/languages/r.py
Normal file
155
.venv/lib/python3.8/site-packages/pre_commit/languages/r.py
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
import contextlib
|
||||
import os
|
||||
import shlex
|
||||
import shutil
|
||||
from typing import Generator
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
from pre_commit.envcontext import envcontext
|
||||
from pre_commit.envcontext import PatchesT
|
||||
from pre_commit.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
|
||||
|
||||
ENVIRONMENT_DIR = 'renv'
|
||||
RSCRIPT_OPTS = ('--no-save', '--no-restore', '--no-site-file', '--no-environ')
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
healthy = helpers.basic_healthy
|
||||
|
||||
|
||||
def get_env_patch(venv: str) -> PatchesT:
|
||||
return (
|
||||
('R_PROFILE_USER', os.path.join(venv, 'activate.R')),
|
||||
('RENV_PROJECT', UNSET),
|
||||
)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_env(
|
||||
prefix: Prefix,
|
||||
language_version: str,
|
||||
) -> Generator[None, None, None]:
|
||||
envdir = _get_env_dir(prefix, language_version)
|
||||
with envcontext(get_env_patch(envdir)):
|
||||
yield
|
||||
|
||||
|
||||
def _get_env_dir(prefix: Prefix, version: str) -> str:
|
||||
return prefix.path(helpers.environment_dir(ENVIRONMENT_DIR, version))
|
||||
|
||||
|
||||
def _prefix_if_non_local_file_entry(
|
||||
entry: Sequence[str],
|
||||
prefix: Prefix,
|
||||
src: str,
|
||||
) -> Sequence[str]:
|
||||
if entry[1] == '-e':
|
||||
return entry[1:]
|
||||
else:
|
||||
if src == 'local':
|
||||
path = entry[1]
|
||||
else:
|
||||
path = prefix.path(entry[1])
|
||||
return (path,)
|
||||
|
||||
|
||||
def _rscript_exec() -> str:
|
||||
return os.path.join(os.getenv('R_HOME', ''), 'Rscript')
|
||||
|
||||
|
||||
def _entry_validate(entry: Sequence[str]) -> None:
|
||||
"""
|
||||
Allowed entries:
|
||||
# Rscript -e expr
|
||||
# Rscript path/to/file
|
||||
"""
|
||||
if entry[0] != 'Rscript':
|
||||
raise ValueError('entry must start with `Rscript`.')
|
||||
|
||||
if entry[1] == '-e':
|
||||
if len(entry) > 3:
|
||||
raise ValueError('You can supply at most one expression.')
|
||||
elif len(entry) > 2:
|
||||
raise ValueError(
|
||||
'The only valid syntax is `Rscript -e {expr}`',
|
||||
'or `Rscript path/to/hook/script`',
|
||||
)
|
||||
|
||||
|
||||
def _cmd_from_hook(hook: Hook) -> Tuple[str, ...]:
|
||||
entry = shlex.split(hook.entry)
|
||||
_entry_validate(entry)
|
||||
|
||||
return (
|
||||
*entry[:1], *RSCRIPT_OPTS,
|
||||
*_prefix_if_non_local_file_entry(entry, hook.prefix, hook.src),
|
||||
*hook.args,
|
||||
)
|
||||
|
||||
|
||||
def install_environment(
|
||||
prefix: Prefix,
|
||||
version: str,
|
||||
additional_dependencies: Sequence[str],
|
||||
) -> None:
|
||||
env_dir = _get_env_dir(prefix, version)
|
||||
with clean_path_on_failure(env_dir):
|
||||
os.makedirs(env_dir, exist_ok=True)
|
||||
shutil.copy(prefix.path('renv.lock'), env_dir)
|
||||
shutil.copytree(prefix.path('renv'), os.path.join(env_dir, 'renv'))
|
||||
|
||||
cmd_output_b(
|
||||
_rscript_exec(), '--vanilla', '-e',
|
||||
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)
|
||||
}}
|
||||
""",
|
||||
cwd=env_dir,
|
||||
)
|
||||
if additional_dependencies:
|
||||
with in_env(prefix, version):
|
||||
cmd_output_b(
|
||||
_rscript_exec(), *RSCRIPT_OPTS, '-e',
|
||||
'renv::install(commandArgs(trailingOnly = TRUE))',
|
||||
*additional_dependencies,
|
||||
cwd=env_dir,
|
||||
)
|
||||
|
||||
|
||||
def run_hook(
|
||||
hook: Hook,
|
||||
file_args: Sequence[str],
|
||||
color: bool,
|
||||
) -> Tuple[int, bytes]:
|
||||
with in_env(hook.prefix, hook.language_version):
|
||||
return helpers.run_xargs(
|
||||
hook, _cmd_from_hook(hook), file_args, color=color,
|
||||
)
|
||||
151
.venv/lib/python3.8/site-packages/pre_commit/languages/ruby.py
Normal file
151
.venv/lib/python3.8/site-packages/pre_commit/languages/ruby.py
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
import contextlib
|
||||
import functools
|
||||
import os.path
|
||||
import shutil
|
||||
import tarfile
|
||||
from typing import Generator
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
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.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'
|
||||
healthy = helpers.basic_healthy
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=1)
|
||||
def get_default_version() -> str:
|
||||
if all(helpers.exe_exists(exe) for exe in ('ruby', 'gem')):
|
||||
return 'system'
|
||||
else:
|
||||
return C.DEFAULT
|
||||
|
||||
|
||||
def get_env_patch(
|
||||
venv: str,
|
||||
language_version: str,
|
||||
) -> PatchesT:
|
||||
patches: PatchesT = (
|
||||
('GEM_HOME', os.path.join(venv, 'gems')),
|
||||
('GEM_PATH', UNSET),
|
||||
('BUNDLE_IGNORE_CONFIG', '1'),
|
||||
)
|
||||
if language_version == 'system':
|
||||
patches += (
|
||||
(
|
||||
'PATH', (
|
||||
os.path.join(venv, 'gems', 'bin'), os.pathsep,
|
||||
Var('PATH'),
|
||||
),
|
||||
),
|
||||
)
|
||||
else: # pragma: win32 no cover
|
||||
patches += (
|
||||
('RBENV_ROOT', venv),
|
||||
(
|
||||
'PATH', (
|
||||
os.path.join(venv, 'gems', 'bin'), os.pathsep,
|
||||
os.path.join(venv, 'shims'), os.pathsep,
|
||||
os.path.join(venv, 'bin'), os.pathsep, Var('PATH'),
|
||||
),
|
||||
),
|
||||
)
|
||||
if language_version not in {'system', 'default'}: # pragma: win32 no cover
|
||||
patches += (('RBENV_VERSION', language_version),)
|
||||
|
||||
return patches
|
||||
|
||||
|
||||
@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)):
|
||||
yield
|
||||
|
||||
|
||||
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: Prefix,
|
||||
version: str,
|
||||
) -> None: # pragma: win32 no cover
|
||||
directory = helpers.environment_dir(ENVIRONMENT_DIR, version)
|
||||
|
||||
_extract_resource('rbenv.tar.gz', prefix.path('.'))
|
||||
shutil.move(prefix.path('rbenv'), prefix.path(directory))
|
||||
|
||||
# Only install ruby-build if the version is specified
|
||||
if version != C.DEFAULT:
|
||||
plugins_dir = prefix.path(directory, 'plugins')
|
||||
_extract_resource('ruby-download.tar.gz', plugins_dir)
|
||||
_extract_resource('ruby-build.tar.gz', plugins_dir)
|
||||
|
||||
|
||||
def _install_ruby(
|
||||
prefix: Prefix,
|
||||
version: str,
|
||||
) -> None: # pragma: win32 no cover
|
||||
try:
|
||||
helpers.run_setup_cmd(prefix, ('rbenv', 'download', version))
|
||||
except CalledProcessError: # pragma: no cover (usually find with download)
|
||||
# Failed to download from mirror for some reason, build it instead
|
||||
helpers.run_setup_cmd(prefix, ('rbenv', 'install', version))
|
||||
|
||||
|
||||
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'))
|
||||
|
||||
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',
|
||||
*prefix.star('.gem'), *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)
|
||||
106
.venv/lib/python3.8/site-packages/pre_commit/languages/rust.py
Normal file
106
.venv/lib/python3.8/site-packages/pre_commit/languages/rust.py
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
import contextlib
|
||||
import os.path
|
||||
from typing import Generator
|
||||
from typing import Sequence
|
||||
from typing import Set
|
||||
from typing import Tuple
|
||||
|
||||
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.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 = 'rustenv'
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
healthy = helpers.basic_healthy
|
||||
|
||||
|
||||
def get_env_patch(target_dir: str) -> PatchesT:
|
||||
return (
|
||||
('PATH', (os.path.join(target_dir, 'bin'), os.pathsep, Var('PATH'))),
|
||||
)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_env(prefix: Prefix) -> Generator[None, None, None]:
|
||||
target_dir = prefix.path(
|
||||
helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT),
|
||||
)
|
||||
with envcontext(get_env_patch(target_dir)):
|
||||
yield
|
||||
|
||||
|
||||
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', {})
|
||||
for dep in additional_dependencies:
|
||||
name, _, spec = dep.partition(':')
|
||||
cargo_toml['dependencies'][name] = spec or '*'
|
||||
f.seek(0)
|
||||
toml.dump(cargo_toml, f)
|
||||
f.truncate()
|
||||
|
||||
|
||||
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),
|
||||
)
|
||||
|
||||
# There are two cases where we might want to specify more dependencies:
|
||||
# as dependencies for the library being built, and as binary packages
|
||||
# to be `cargo install`'d.
|
||||
#
|
||||
# Unlike e.g. Python, if we just `cargo install` a library, it won't be
|
||||
# used for compilation. And if we add a crate providing a binary to the
|
||||
# `Cargo.toml`, the binary won't be built.
|
||||
#
|
||||
# Because of this, we allow specifying "cli" dependencies by prefixing
|
||||
# with 'cli:'.
|
||||
cli_deps = {
|
||||
dep for dep in additional_dependencies if dep.startswith('cli:')
|
||||
}
|
||||
lib_deps = set(additional_dependencies) - cli_deps
|
||||
|
||||
if len(lib_deps) > 0:
|
||||
_add_dependencies(prefix.path('Cargo.toml'), lib_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, _, version = cli_dep.partition(':')
|
||||
if version != '':
|
||||
packages_to_install.add((package, '--version', version))
|
||||
else:
|
||||
packages_to_install.add((package,))
|
||||
|
||||
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):
|
||||
return helpers.run_xargs(hook, hook.cmd, file_args, color=color)
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
from pre_commit.hook import Hook
|
||||
from pre_commit.languages import helpers
|
||||
|
||||
ENVIRONMENT_DIR = None
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
healthy = helpers.basic_healthy
|
||||
install_environment = helpers.no_install
|
||||
|
||||
|
||||
def run_hook(
|
||||
hook: Hook,
|
||||
file_args: Sequence[str],
|
||||
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)
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
import contextlib
|
||||
import os
|
||||
from typing import Generator
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
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
|
||||
|
||||
ENVIRONMENT_DIR = 'swift_env'
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
healthy = helpers.basic_healthy
|
||||
BUILD_DIR = '.build'
|
||||
BUILD_CONFIG = 'release'
|
||||
|
||||
|
||||
def get_env_patch(venv: str) -> PatchesT: # pragma: win32 no cover
|
||||
bin_path = os.path.join(venv, BUILD_DIR, BUILD_CONFIG)
|
||||
return (('PATH', (bin_path, os.pathsep, Var('PATH'))),)
|
||||
|
||||
|
||||
@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),
|
||||
)
|
||||
with envcontext(get_env_patch(envdir)):
|
||||
yield
|
||||
|
||||
|
||||
def install_environment(
|
||||
prefix: Prefix, version: str, additional_dependencies: Sequence[str],
|
||||
) -> 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),
|
||||
)
|
||||
|
||||
# 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)
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
from pre_commit.hook import Hook
|
||||
from pre_commit.languages import helpers
|
||||
|
||||
|
||||
ENVIRONMENT_DIR = None
|
||||
get_default_version = helpers.basic_get_default_version
|
||||
healthy = helpers.basic_healthy
|
||||
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)
|
||||
Loading…
Add table
Add a link
Reference in a new issue