Adding upstream version 2.5.1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
080d7f9289
commit
bb6dbf8636
37 changed files with 457 additions and 213 deletions
|
@ -84,7 +84,9 @@ def _check_hooks_still_exist_at_rev(
|
|||
)
|
||||
|
||||
|
||||
REV_LINE_RE = re.compile(r'^(\s+)rev:(\s*)([^\s#]+)(.*)(\r?\n)$', re.DOTALL)
|
||||
REV_LINE_RE = re.compile(
|
||||
r'^(\s+)rev:(\s*)([\'"]?)([^\s#]+)(.*)(\r?\n)$', re.DOTALL,
|
||||
)
|
||||
|
||||
|
||||
def _original_lines(
|
||||
|
@ -116,15 +118,15 @@ def _write_new_config(path: str, rev_infos: List[Optional[RevInfo]]) -> None:
|
|||
continue
|
||||
match = REV_LINE_RE.match(lines[idx])
|
||||
assert match is not None
|
||||
new_rev_s = yaml_dump({'rev': rev_info.rev})
|
||||
new_rev_s = yaml_dump({'rev': rev_info.rev}, default_style=match[3])
|
||||
new_rev = new_rev_s.split(':', 1)[1].strip()
|
||||
if rev_info.frozen is not None:
|
||||
comment = f' # frozen: {rev_info.frozen}'
|
||||
elif match[4].strip().startswith('# frozen:'):
|
||||
elif match[5].strip().startswith('# frozen:'):
|
||||
comment = ''
|
||||
else:
|
||||
comment = match[4]
|
||||
lines[idx] = f'{match[1]}rev:{match[2]}{new_rev}{comment}{match[5]}'
|
||||
comment = match[5]
|
||||
lines[idx] = f'{match[1]}rev:{match[2]}{new_rev}{comment}{match[6]}'
|
||||
|
||||
with open(path, 'w', newline='') as f:
|
||||
f.write(''.join(lines))
|
||||
|
|
|
@ -150,6 +150,7 @@ def _pre_push_ns(
|
|||
_EXPECTED_ARG_LENGTH_BY_HOOK = {
|
||||
'commit-msg': 1,
|
||||
'post-checkout': 3,
|
||||
'post-commit': 0,
|
||||
'pre-commit': 0,
|
||||
'pre-merge-commit': 0,
|
||||
'pre-push': 2,
|
||||
|
@ -186,7 +187,7 @@ def _run_ns(
|
|||
return _pre_push_ns(color, args, stdin)
|
||||
elif hook_type in {'commit-msg', 'prepare-commit-msg'}:
|
||||
return _ns(hook_type, color, commit_msg_filename=args[0])
|
||||
elif hook_type in {'pre-merge-commit', 'pre-commit'}:
|
||||
elif hook_type in {'post-commit', 'pre-merge-commit', 'pre-commit'}:
|
||||
return _ns(hook_type, color)
|
||||
elif hook_type == 'post-checkout':
|
||||
return _ns(
|
||||
|
|
|
@ -2,6 +2,7 @@ import re
|
|||
|
||||
import yaml
|
||||
|
||||
from pre_commit.clientlib import load_config
|
||||
from pre_commit.util import yaml_load
|
||||
|
||||
|
||||
|
@ -43,6 +44,9 @@ def _migrate_sha_to_rev(contents: str) -> str:
|
|||
|
||||
|
||||
def migrate_config(config_file: str, quiet: bool = False) -> int:
|
||||
# ensure that the configuration is a valid pre-commit configuration
|
||||
load_config(config_file)
|
||||
|
||||
with open(config_file) as f:
|
||||
orig_contents = contents = f.read()
|
||||
|
||||
|
|
|
@ -72,13 +72,7 @@ def filter_by_include_exclude(
|
|||
|
||||
|
||||
class Classifier:
|
||||
def __init__(self, filenames: Sequence[str]) -> None:
|
||||
# on windows we normalize all filenames to use forward slashes
|
||||
# this makes it easier to filter using the `files:` regex
|
||||
# this also makes improperly quoted shell-based hooks work better
|
||||
# see #1173
|
||||
if os.altsep == '/' and os.sep == '\\':
|
||||
filenames = [f.replace(os.sep, os.altsep) for f in filenames]
|
||||
def __init__(self, filenames: Collection[str]) -> None:
|
||||
self.filenames = [f for f in filenames if os.path.lexists(f)]
|
||||
|
||||
@functools.lru_cache(maxsize=None)
|
||||
|
@ -105,6 +99,22 @@ class Classifier:
|
|||
names = self.by_types(names, hook.types, hook.exclude_types)
|
||||
return tuple(names)
|
||||
|
||||
@classmethod
|
||||
def from_config(
|
||||
cls,
|
||||
filenames: Collection[str],
|
||||
include: str,
|
||||
exclude: str,
|
||||
) -> 'Classifier':
|
||||
# on windows we normalize all filenames to use forward slashes
|
||||
# this makes it easier to filter using the `files:` regex
|
||||
# this also makes improperly quoted shell-based hooks work better
|
||||
# see #1173
|
||||
if os.altsep == '/' and os.sep == '\\':
|
||||
filenames = [f.replace(os.sep, os.altsep) for f in filenames]
|
||||
filenames = filter_by_include_exclude(filenames, include, exclude)
|
||||
return Classifier(filenames)
|
||||
|
||||
|
||||
def _get_skips(environ: EnvironT) -> Set[str]:
|
||||
skips = environ.get('SKIP', '')
|
||||
|
@ -221,7 +231,8 @@ def _compute_cols(hooks: Sequence[Hook]) -> int:
|
|||
|
||||
|
||||
def _all_filenames(args: argparse.Namespace) -> Collection[str]:
|
||||
if args.hook_stage == 'post-checkout': # no files for post-checkout
|
||||
# these hooks do not operate on files
|
||||
if args.hook_stage in {'post-checkout', 'post-commit'}:
|
||||
return ()
|
||||
elif args.hook_stage in {'prepare-commit-msg', 'commit-msg'}:
|
||||
return (args.commit_msg_filename,)
|
||||
|
@ -246,10 +257,9 @@ def _run_hooks(
|
|||
"""Actually run the hooks."""
|
||||
skips = _get_skips(environ)
|
||||
cols = _compute_cols(hooks)
|
||||
filenames = filter_by_include_exclude(
|
||||
classifier = Classifier.from_config(
|
||||
_all_filenames(args), config['files'], config['exclude'],
|
||||
)
|
||||
classifier = Classifier(filenames)
|
||||
retval = 0
|
||||
for hook in hooks:
|
||||
retval |= _run_single_hook(
|
||||
|
@ -323,6 +333,12 @@ def run(
|
|||
f'`--hook-stage {args.hook_stage}`',
|
||||
)
|
||||
return 1
|
||||
# prevent recursive post-checkout hooks (#1418)
|
||||
if (
|
||||
args.hook_stage == 'post-checkout' and
|
||||
environ.get('_PRE_COMMIT_SKIP_POST_CHECKOUT')
|
||||
):
|
||||
return 0
|
||||
|
||||
# Expose from-ref / to-ref as environment variables for hooks to consume
|
||||
if args.from_ref and args.to_ref:
|
||||
|
@ -340,6 +356,9 @@ def run(
|
|||
if args.checkout_type:
|
||||
environ['PRE_COMMIT_CHECKOUT_TYPE'] = args.checkout_type
|
||||
|
||||
# Set pre_commit flag
|
||||
environ['PRE_COMMIT'] = '1'
|
||||
|
||||
with contextlib.ExitStack() as exit_stack:
|
||||
if stash:
|
||||
exit_stack.enter_context(staged_files_only(store.directory))
|
||||
|
|
|
@ -17,8 +17,8 @@ VERSION = importlib_metadata.version('pre_commit')
|
|||
|
||||
# `manual` is not invoked by any installed git hook. See #719
|
||||
STAGES = (
|
||||
'commit', 'merge-commit', 'prepare-commit-msg', 'commit-msg', 'manual',
|
||||
'post-checkout', 'push',
|
||||
'commit', 'merge-commit', 'prepare-commit-msg', 'commit-msg',
|
||||
'post-commit', 'manual', 'post-checkout', 'push',
|
||||
)
|
||||
|
||||
DEFAULT = 'default'
|
||||
|
|
|
@ -158,7 +158,8 @@ def init_repo(path: str, remote: str) -> None:
|
|||
remote = os.path.abspath(remote)
|
||||
|
||||
env = no_git_env()
|
||||
cmd_output_b('git', 'init', path, env=env)
|
||||
# avoid the user's template so that hooks do not recurse
|
||||
cmd_output_b('git', 'init', '--template=', path, env=env)
|
||||
cmd_output_b('git', 'remote', 'add', 'origin', remote, cwd=path, env=env)
|
||||
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ 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 python_venv
|
||||
from pre_commit.languages import ruby
|
||||
from pre_commit.languages import rust
|
||||
from pre_commit.languages import script
|
||||
|
@ -49,7 +48,6 @@ languages = {
|
|||
'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
|
||||
'python_venv': Language(name='python_venv', ENVIRONMENT_DIR=python_venv.ENVIRONMENT_DIR, get_default_version=python_venv.get_default_version, healthy=python_venv.healthy, install_environment=python_venv.install_environment, run_hook=python_venv.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
|
||||
|
@ -57,4 +55,6 @@ languages = {
|
|||
'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)
|
||||
|
|
|
@ -18,7 +18,7 @@ from pre_commit.xargs import xargs
|
|||
if TYPE_CHECKING:
|
||||
from typing import NoReturn
|
||||
|
||||
FIXED_RANDOM_SEED = 1542676186
|
||||
FIXED_RANDOM_SEED = 1542676187
|
||||
|
||||
|
||||
def run_setup_cmd(prefix: Prefix, cmd: Tuple[str, ...]) -> None:
|
||||
|
@ -92,7 +92,7 @@ def _shuffled(seq: Sequence[str]) -> List[str]:
|
|||
fixed_random.seed(FIXED_RANDOM_SEED, version=1)
|
||||
|
||||
seq = list(seq)
|
||||
random.shuffle(seq, random=fixed_random.random)
|
||||
fixed_random.shuffle(seq)
|
||||
return seq
|
||||
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ def install_environment(
|
|||
|
||||
# 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 = f'\\\\?\\{os.path.normpath(envdir)}'
|
||||
envdir = fr'\\?\{os.path.normpath(envdir)}'
|
||||
with clean_path_on_failure(envdir):
|
||||
cmd = [
|
||||
sys.executable, '-mnodeenv', '--prebuilt', '--clean-src', envdir,
|
||||
|
|
|
@ -2,8 +2,7 @@ import contextlib
|
|||
import functools
|
||||
import os
|
||||
import sys
|
||||
from typing import Callable
|
||||
from typing import ContextManager
|
||||
from typing import Dict
|
||||
from typing import Generator
|
||||
from typing import Optional
|
||||
from typing import Sequence
|
||||
|
@ -26,6 +25,28 @@ from pre_commit.util import cmd_output_b
|
|||
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) 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'
|
||||
|
@ -34,6 +55,7 @@ def bin_dir(venv: str) -> str:
|
|||
|
||||
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'))),
|
||||
|
@ -45,9 +67,10 @@ def _find_by_py_launcher(
|
|||
) -> 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:
|
||||
cmd = ('py', f'-{num}', '-c', 'import sys; print(sys.executable)')
|
||||
return cmd_output(*cmd)[1].strip()
|
||||
return cmd_output(*cmd, env=env)[1].strip()
|
||||
except CalledProcessError:
|
||||
pass
|
||||
return None
|
||||
|
@ -115,6 +138,9 @@ def _sys_executable_matches(version: str) -> bool:
|
|||
|
||||
|
||||
def norm_version(version: str) -> str:
|
||||
if version == C.DEFAULT:
|
||||
return os.path.realpath(sys.executable)
|
||||
|
||||
# first see if our current executable is appropriate
|
||||
if _sys_executable_matches(version):
|
||||
return sys.executable
|
||||
|
@ -139,70 +165,59 @@ def norm_version(version: str) -> str:
|
|||
return os.path.expanduser(version)
|
||||
|
||||
|
||||
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: 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: Prefix, language_version: str) -> bool:
|
||||
envdir = helpers.environment_dir(_dir, language_version)
|
||||
exe_name = 'python.exe' if sys.platform == 'win32' else 'python'
|
||||
py_exe = prefix.path(bin_dir(envdir), exe_name)
|
||||
with in_env(prefix, language_version):
|
||||
retcode, _, _ = cmd_output_b(
|
||||
py_exe, '-c', 'import ctypes, datetime, io, os, ssl, weakref',
|
||||
cwd='/',
|
||||
retcode=None,
|
||||
)
|
||||
return retcode == 0
|
||||
|
||||
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: Prefix,
|
||||
version: str,
|
||||
additional_dependencies: Sequence[str],
|
||||
) -> None:
|
||||
directory = helpers.environment_dir(_dir, version)
|
||||
install = ('python', '-mpip', 'install', '.', *additional_dependencies)
|
||||
|
||||
env_dir = prefix.path(directory)
|
||||
with clean_path_on_failure(env_dir):
|
||||
if version != C.DEFAULT:
|
||||
python = norm_version(version)
|
||||
else:
|
||||
python = os.path.realpath(sys.executable)
|
||||
_make_venv(env_dir, python)
|
||||
with in_env(prefix, version):
|
||||
helpers.run_setup_cmd(prefix, install)
|
||||
|
||||
return in_env, healthy, run_hook, install_environment
|
||||
@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 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='/')
|
||||
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 = 'python.exe' if sys.platform == 'win32' else 'python'
|
||||
py_exe = prefix.path(bin_dir(envdir), exe_name)
|
||||
cfg = _read_pyvenv_cfg(pyvenv_cfg)
|
||||
|
||||
return (
|
||||
'version_info' in cfg and
|
||||
_version_info(py_exe) == cfg['version_info'] and (
|
||||
'base-executable' not in cfg or
|
||||
_version_info(cfg['base-executable']) == cfg['version_info']
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
_interface = py_interface(ENVIRONMENT_DIR, make_venv)
|
||||
in_env, healthy, run_hook, install_environment = _interface
|
||||
def install_environment(
|
||||
prefix: Prefix,
|
||||
version: str,
|
||||
additional_dependencies: Sequence[str],
|
||||
) -> None:
|
||||
envdir = prefix.path(helpers.environment_dir(ENVIRONMENT_DIR, version))
|
||||
python = norm_version(version)
|
||||
venv_cmd = (sys.executable, '-mvirtualenv', envdir, '-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)
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
import os.path
|
||||
|
||||
from pre_commit.languages import python
|
||||
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 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.
|
||||
|
||||
See:
|
||||
- https://github.com/pre-commit/pre-commit/issues/755
|
||||
- https://github.com/pypa/virtualenv/issues/1095
|
||||
- https://bugs.python.org/issue30811
|
||||
"""
|
||||
try:
|
||||
prefix_script = 'import sys; print(sys.real_prefix)'
|
||||
_, prefix, _ = cmd_output(exe, '-c', prefix_script)
|
||||
prefix = prefix.strip()
|
||||
except CalledProcessError:
|
||||
# not created from -mvirtualenv
|
||||
return exe
|
||||
|
||||
if os.name == 'nt':
|
||||
expected = os.path.join(prefix, 'python.exe')
|
||||
else:
|
||||
expected = os.path.join(prefix, 'bin', os.path.basename(exe))
|
||||
|
||||
if os.path.exists(expected):
|
||||
return expected
|
||||
else:
|
||||
return exe
|
||||
|
||||
|
||||
def make_venv(envdir: str, python: str) -> None:
|
||||
cmd_output_b(orig_py_exe(python), '-mvenv', envdir, cwd='/')
|
||||
|
||||
|
||||
_interface = python.py_interface(ENVIRONMENT_DIR, make_venv)
|
||||
in_env, healthy, run_hook, install_environment = _interface
|
|
@ -9,6 +9,7 @@ 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
|
||||
|
@ -28,6 +29,7 @@ def get_env_patch(
|
|||
) -> PatchesT: # pragma: win32 no cover
|
||||
patches: PatchesT = (
|
||||
('GEM_HOME', os.path.join(venv, 'gems')),
|
||||
('GEM_PATH', UNSET),
|
||||
('RBENV_ROOT', venv),
|
||||
('BUNDLE_IGNORE_CONFIG', '1'),
|
||||
(
|
||||
|
|
|
@ -79,7 +79,7 @@ def _add_hook_type_option(parser: argparse.ArgumentParser) -> None:
|
|||
parser.add_argument(
|
||||
'-t', '--hook-type', choices=(
|
||||
'pre-commit', 'pre-merge-commit', 'pre-push',
|
||||
'prepare-commit-msg', 'commit-msg', 'post-checkout',
|
||||
'prepare-commit-msg', 'commit-msg', 'post-commit', 'post-checkout',
|
||||
),
|
||||
action=AppendReplaceDefault,
|
||||
default=['pre-commit'],
|
||||
|
|
|
@ -11,10 +11,13 @@ from pre_commit.store import Store
|
|||
|
||||
|
||||
def check_all_hooks_match_files(config_file: str) -> int:
|
||||
classifier = Classifier(git.get_all_files())
|
||||
config = load_config(config_file)
|
||||
classifier = Classifier.from_config(
|
||||
git.get_all_files(), config['files'], config['exclude'],
|
||||
)
|
||||
retv = 0
|
||||
|
||||
for hook in all_hooks(load_config(config_file), Store()):
|
||||
for hook in all_hooks(config, Store()):
|
||||
if hook.always_run or hook.language == 'fail':
|
||||
continue
|
||||
elif not classifier.filenames_for_hook(hook):
|
||||
|
|
|
@ -28,11 +28,14 @@ def exclude_matches_any(
|
|||
|
||||
def check_useless_excludes(config_file: str) -> int:
|
||||
config = load_config(config_file)
|
||||
classifier = Classifier(git.get_all_files())
|
||||
filenames = git.get_all_files()
|
||||
classifier = Classifier.from_config(
|
||||
filenames, config['files'], config['exclude'],
|
||||
)
|
||||
retv = 0
|
||||
|
||||
exclude = config['exclude']
|
||||
if not exclude_matches_any(classifier.filenames, '', exclude):
|
||||
if not exclude_matches_any(filenames, '', exclude):
|
||||
print(
|
||||
f'The global exclude pattern {exclude!r} does not match any files',
|
||||
)
|
||||
|
|
0
pre_commit/resources/empty_template_go.mod
Normal file
0
pre_commit/resources/empty_template_go.mod
Normal file
|
@ -56,8 +56,10 @@ def _unstaged_changes_cleared(patch_dir: str) -> Generator[None, None, None]:
|
|||
with open(patch_filename, 'wb') as patch_file:
|
||||
patch_file.write(diff_stdout_binary)
|
||||
|
||||
# Clear the working directory of unstaged changes
|
||||
cmd_output_b('git', 'checkout', '--', '.')
|
||||
# prevent recursive post-checkout hooks (#1418)
|
||||
no_checkout_env = dict(os.environ, _PRE_COMMIT_SKIP_POST_CHECKOUT='1')
|
||||
cmd_output_b('git', 'checkout', '--', '.', env=no_checkout_env)
|
||||
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
|
@ -72,8 +74,9 @@ def _unstaged_changes_cleared(patch_dir: str) -> Generator[None, None, None]:
|
|||
# We failed to apply the patch, presumably due to fixes made
|
||||
# by hooks.
|
||||
# Roll back the changes made by hooks.
|
||||
cmd_output_b('git', 'checkout', '--', '.')
|
||||
cmd_output_b('git', 'checkout', '--', '.', env=no_checkout_env)
|
||||
_git_apply(patch_filename)
|
||||
|
||||
logger.info(f'Restored changes from {patch_filename}.')
|
||||
else:
|
||||
# There weren't any staged files so we don't need to do anything
|
||||
|
|
|
@ -30,10 +30,11 @@ def _get_default_directory() -> str:
|
|||
`Store.get_default_directory` can be mocked in tests and
|
||||
`_get_default_directory` can be tested.
|
||||
"""
|
||||
return os.environ.get('PRE_COMMIT_HOME') or os.path.join(
|
||||
ret = os.environ.get('PRE_COMMIT_HOME') or os.path.join(
|
||||
os.environ.get('XDG_CACHE_HOME') or os.path.expanduser('~/.cache'),
|
||||
'pre-commit',
|
||||
)
|
||||
return os.path.realpath(ret)
|
||||
|
||||
|
||||
class Store:
|
||||
|
@ -182,9 +183,9 @@ class Store:
|
|||
return self._new_repo(repo, ref, deps, clone_strategy)
|
||||
|
||||
LOCAL_RESOURCES = (
|
||||
'Cargo.toml', 'main.go', 'main.rs', '.npmignore', 'package.json',
|
||||
'pre_commit_dummy_package.gemspec', 'setup.py', 'environment.yml',
|
||||
'Makefile.PL',
|
||||
'Cargo.toml', 'main.go', 'go.mod', 'main.rs', '.npmignore',
|
||||
'package.json', 'pre_commit_dummy_package.gemspec', 'setup.py',
|
||||
'environment.yml', 'Makefile.PL',
|
||||
)
|
||||
|
||||
def make_local(self, deps: Sequence[str]) -> str:
|
||||
|
|
|
@ -36,10 +36,11 @@ yaml_load = functools.partial(yaml.load, Loader=Loader)
|
|||
Dumper = getattr(yaml, 'CSafeDumper', yaml.SafeDumper)
|
||||
|
||||
|
||||
def yaml_dump(o: Any) -> str:
|
||||
def yaml_dump(o: Any, **kwargs: Any) -> str:
|
||||
# when python/mypy#1484 is solved, this can be `functools.partial`
|
||||
return yaml.dump(
|
||||
o, Dumper=Dumper, default_flow_style=False, indent=4, sort_keys=False,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue