Merging upstream version 2.18.1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
131d7bde70
commit
3396d2e509
116 changed files with 718 additions and 410 deletions
|
@ -1,12 +1,10 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import os.path
|
||||
import re
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import NamedTuple
|
||||
from typing import Optional
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
import pre_commit.constants as C
|
||||
from pre_commit import git
|
||||
|
@ -29,13 +27,13 @@ from pre_commit.util import yaml_load
|
|||
class RevInfo(NamedTuple):
|
||||
repo: str
|
||||
rev: str
|
||||
frozen: Optional[str]
|
||||
frozen: str | None
|
||||
|
||||
@classmethod
|
||||
def from_config(cls, config: Dict[str, Any]) -> 'RevInfo':
|
||||
def from_config(cls, config: dict[str, Any]) -> RevInfo:
|
||||
return cls(config['repo'], config['rev'], None)
|
||||
|
||||
def update(self, tags_only: bool, freeze: bool) -> 'RevInfo':
|
||||
def update(self, tags_only: bool, freeze: bool) -> RevInfo:
|
||||
git_cmd = ('git', *git.NO_FS_MONITOR)
|
||||
|
||||
if tags_only:
|
||||
|
@ -61,6 +59,9 @@ class RevInfo(NamedTuple):
|
|||
except CalledProcessError:
|
||||
cmd = (*git_cmd, 'rev-parse', 'FETCH_HEAD')
|
||||
rev = cmd_output(*cmd, cwd=tmp)[1].strip()
|
||||
else:
|
||||
if tags_only:
|
||||
rev = git.get_best_candidate_tag(rev, tmp)
|
||||
|
||||
frozen = None
|
||||
if freeze:
|
||||
|
@ -76,7 +77,7 @@ class RepositoryCannotBeUpdatedError(RuntimeError):
|
|||
|
||||
|
||||
def _check_hooks_still_exist_at_rev(
|
||||
repo_config: Dict[str, Any],
|
||||
repo_config: dict[str, Any],
|
||||
info: RevInfo,
|
||||
store: Store,
|
||||
) -> None:
|
||||
|
@ -101,9 +102,9 @@ REV_LINE_RE = re.compile(r'^(\s+)rev:(\s*)([\'"]?)([^\s#]+)(.*)(\r?\n)$')
|
|||
|
||||
def _original_lines(
|
||||
path: str,
|
||||
rev_infos: List[Optional[RevInfo]],
|
||||
rev_infos: list[RevInfo | None],
|
||||
retry: bool = False,
|
||||
) -> Tuple[List[str], List[int]]:
|
||||
) -> tuple[list[str], list[int]]:
|
||||
"""detect `rev:` lines or reformat the file"""
|
||||
with open(path, newline='') as f:
|
||||
original = f.read()
|
||||
|
@ -120,7 +121,7 @@ def _original_lines(
|
|||
return _original_lines(path, rev_infos, retry=True)
|
||||
|
||||
|
||||
def _write_new_config(path: str, rev_infos: List[Optional[RevInfo]]) -> None:
|
||||
def _write_new_config(path: str, rev_infos: list[RevInfo | None]) -> None:
|
||||
lines, idxs = _original_lines(path, rev_infos)
|
||||
|
||||
for idx, rev_info in zip(idxs, rev_infos):
|
||||
|
@ -152,7 +153,7 @@ def autoupdate(
|
|||
"""Auto-update the pre-commit config to the latest versions of repos."""
|
||||
migrate_config(config_file, quiet=True)
|
||||
retv = 0
|
||||
rev_infos: List[Optional[RevInfo]] = []
|
||||
rev_infos: list[RevInfo | None] = []
|
||||
changed = False
|
||||
|
||||
config = load_config(config_file)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import os.path
|
||||
|
||||
from pre_commit import output
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import os.path
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import Set
|
||||
from typing import Tuple
|
||||
|
||||
import pre_commit.constants as C
|
||||
from pre_commit import output
|
||||
|
@ -17,9 +16,9 @@ from pre_commit.store import Store
|
|||
|
||||
def _mark_used_repos(
|
||||
store: Store,
|
||||
all_repos: Dict[Tuple[str, str], str],
|
||||
unused_repos: Set[Tuple[str, str]],
|
||||
repo: Dict[str, Any],
|
||||
all_repos: dict[tuple[str, str], str],
|
||||
unused_repos: set[tuple[str, str]],
|
||||
repo: dict[str, Any],
|
||||
) -> None:
|
||||
if repo['repo'] == META:
|
||||
return
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os.path
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import Optional
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
from pre_commit.commands.run import run
|
||||
from pre_commit.envcontext import envcontext
|
||||
|
@ -18,7 +18,7 @@ def _run_legacy(
|
|||
hook_type: str,
|
||||
hook_dir: str,
|
||||
args: Sequence[str],
|
||||
) -> Tuple[int, bytes]:
|
||||
) -> tuple[int, bytes]:
|
||||
if os.environ.get('PRE_COMMIT_RUNNING_LEGACY'):
|
||||
raise SystemExit(
|
||||
f"bug: pre-commit's script is installed in migration mode\n"
|
||||
|
@ -69,16 +69,16 @@ def _ns(
|
|||
color: bool,
|
||||
*,
|
||||
all_files: bool = False,
|
||||
remote_branch: Optional[str] = None,
|
||||
local_branch: Optional[str] = None,
|
||||
from_ref: Optional[str] = None,
|
||||
to_ref: Optional[str] = None,
|
||||
remote_name: Optional[str] = None,
|
||||
remote_url: Optional[str] = None,
|
||||
commit_msg_filename: Optional[str] = None,
|
||||
checkout_type: Optional[str] = None,
|
||||
is_squash_merge: Optional[str] = None,
|
||||
rewrite_command: Optional[str] = None,
|
||||
remote_branch: str | None = None,
|
||||
local_branch: str | None = None,
|
||||
from_ref: str | None = None,
|
||||
to_ref: str | None = None,
|
||||
remote_name: str | None = None,
|
||||
remote_url: str | None = None,
|
||||
commit_msg_filename: str | None = None,
|
||||
checkout_type: str | None = None,
|
||||
is_squash_merge: str | None = None,
|
||||
rewrite_command: str | None = None,
|
||||
) -> argparse.Namespace:
|
||||
return argparse.Namespace(
|
||||
color=color,
|
||||
|
@ -109,7 +109,7 @@ def _pre_push_ns(
|
|||
color: bool,
|
||||
args: Sequence[str],
|
||||
stdin: bytes,
|
||||
) -> Optional[argparse.Namespace]:
|
||||
) -> argparse.Namespace | None:
|
||||
remote_name = args[0]
|
||||
remote_url = args[1]
|
||||
|
||||
|
@ -197,7 +197,7 @@ def _run_ns(
|
|||
color: bool,
|
||||
args: Sequence[str],
|
||||
stdin: bytes,
|
||||
) -> Optional[argparse.Namespace]:
|
||||
) -> argparse.Namespace | None:
|
||||
_check_args_length(hook_type, args)
|
||||
if hook_type == 'pre-push':
|
||||
return _pre_push_ns(color, args, stdin)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os.path
|
||||
from typing import Sequence
|
||||
|
||||
from pre_commit.commands.install_uninstall import install
|
||||
from pre_commit.store import Store
|
||||
|
@ -14,7 +15,7 @@ def init_templatedir(
|
|||
config_file: str,
|
||||
store: Store,
|
||||
directory: str,
|
||||
hook_types: Sequence[str],
|
||||
hook_types: list[str] | None,
|
||||
skip_on_missing_config: bool = True,
|
||||
) -> int:
|
||||
install(
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os.path
|
||||
import shlex
|
||||
import shutil
|
||||
import sys
|
||||
from typing import Optional
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
|
||||
from pre_commit import git
|
||||
from pre_commit import output
|
||||
from pre_commit.clientlib import InvalidConfigError
|
||||
from pre_commit.clientlib import load_config
|
||||
from pre_commit.repository import all_hooks
|
||||
from pre_commit.repository import install_hook_envs
|
||||
|
@ -32,11 +32,23 @@ TEMPLATE_START = '# start templated\n'
|
|||
TEMPLATE_END = '# end templated\n'
|
||||
|
||||
|
||||
def _hook_types(cfg_filename: str, hook_types: list[str] | None) -> list[str]:
|
||||
if hook_types is not None:
|
||||
return hook_types
|
||||
else:
|
||||
try:
|
||||
cfg = load_config(cfg_filename)
|
||||
except InvalidConfigError:
|
||||
return ['pre-commit']
|
||||
else:
|
||||
return cfg['default_install_hook_types']
|
||||
|
||||
|
||||
def _hook_paths(
|
||||
hook_type: str,
|
||||
git_dir: Optional[str] = None,
|
||||
) -> Tuple[str, str]:
|
||||
git_dir = git_dir if git_dir is not None else git.get_git_dir()
|
||||
git_dir: str | None = None,
|
||||
) -> tuple[str, str]:
|
||||
git_dir = git_dir if git_dir is not None else git.get_git_common_dir()
|
||||
pth = os.path.join(git_dir, 'hooks', hook_type)
|
||||
return pth, f'{pth}.legacy'
|
||||
|
||||
|
@ -54,7 +66,7 @@ def _install_hook_script(
|
|||
hook_type: str,
|
||||
overwrite: bool = False,
|
||||
skip_on_missing_config: bool = False,
|
||||
git_dir: Optional[str] = None,
|
||||
git_dir: str | None = None,
|
||||
) -> None:
|
||||
hook_path, legacy_path = _hook_paths(hook_type, git_dir=git_dir)
|
||||
|
||||
|
@ -103,11 +115,11 @@ def _install_hook_script(
|
|||
def install(
|
||||
config_file: str,
|
||||
store: Store,
|
||||
hook_types: Sequence[str],
|
||||
hook_types: list[str] | None,
|
||||
overwrite: bool = False,
|
||||
hooks: bool = False,
|
||||
skip_on_missing_config: bool = False,
|
||||
git_dir: Optional[str] = None,
|
||||
git_dir: str | None = None,
|
||||
) -> int:
|
||||
if git_dir is None and git.has_core_hookpaths_set():
|
||||
logger.error(
|
||||
|
@ -116,7 +128,7 @@ def install(
|
|||
)
|
||||
return 1
|
||||
|
||||
for hook_type in hook_types:
|
||||
for hook_type in _hook_types(config_file, hook_types):
|
||||
_install_hook_script(
|
||||
config_file, hook_type,
|
||||
overwrite=overwrite,
|
||||
|
@ -150,7 +162,7 @@ def _uninstall_hook_script(hook_type: str) -> None:
|
|||
output.write_line(f'Restored previous hooks to {hook_path}')
|
||||
|
||||
|
||||
def uninstall(hook_types: Sequence[str]) -> int:
|
||||
for hook_type in hook_types:
|
||||
def uninstall(config_file: str, hook_types: list[str] | None) -> int:
|
||||
for hook_type in _hook_types(config_file, hook_types):
|
||||
_uninstall_hook_script(hook_type)
|
||||
return 0
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import textwrap
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import contextlib
|
||||
import functools
|
||||
|
@ -9,12 +11,8 @@ import time
|
|||
import unicodedata
|
||||
from typing import Any
|
||||
from typing import Collection
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import MutableMapping
|
||||
from typing import Sequence
|
||||
from typing import Set
|
||||
from typing import Tuple
|
||||
|
||||
from identify.identify import tags_from_path
|
||||
|
||||
|
@ -62,7 +60,7 @@ def filter_by_include_exclude(
|
|||
names: Collection[str],
|
||||
include: str,
|
||||
exclude: str,
|
||||
) -> List[str]:
|
||||
) -> list[str]:
|
||||
include_re, exclude_re = re.compile(include), re.compile(exclude)
|
||||
return [
|
||||
filename for filename in names
|
||||
|
@ -76,7 +74,7 @@ class Classifier:
|
|||
self.filenames = [f for f in filenames if os.path.lexists(f)]
|
||||
|
||||
@functools.lru_cache(maxsize=None)
|
||||
def _types_for_file(self, filename: str) -> Set[str]:
|
||||
def _types_for_file(self, filename: str) -> set[str]:
|
||||
return tags_from_path(filename)
|
||||
|
||||
def by_types(
|
||||
|
@ -85,7 +83,7 @@ class Classifier:
|
|||
types: Collection[str],
|
||||
types_or: Collection[str],
|
||||
exclude_types: Collection[str],
|
||||
) -> List[str]:
|
||||
) -> list[str]:
|
||||
types = frozenset(types)
|
||||
types_or = frozenset(types_or)
|
||||
exclude_types = frozenset(exclude_types)
|
||||
|
@ -100,7 +98,7 @@ class Classifier:
|
|||
ret.append(filename)
|
||||
return ret
|
||||
|
||||
def filenames_for_hook(self, hook: Hook) -> Tuple[str, ...]:
|
||||
def filenames_for_hook(self, hook: Hook) -> tuple[str, ...]:
|
||||
names = self.filenames
|
||||
names = filter_by_include_exclude(names, hook.files, hook.exclude)
|
||||
names = self.by_types(
|
||||
|
@ -117,7 +115,7 @@ class Classifier:
|
|||
filenames: Collection[str],
|
||||
include: str,
|
||||
exclude: str,
|
||||
) -> 'Classifier':
|
||||
) -> 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
|
||||
|
@ -128,7 +126,7 @@ class Classifier:
|
|||
return Classifier(filenames)
|
||||
|
||||
|
||||
def _get_skips(environ: MutableMapping[str, str]) -> Set[str]:
|
||||
def _get_skips(environ: MutableMapping[str, str]) -> set[str]:
|
||||
skips = environ.get('SKIP', '')
|
||||
return {skip.strip() for skip in skips.split(',') if skip.strip()}
|
||||
|
||||
|
@ -144,12 +142,12 @@ def _subtle_line(s: str, use_color: bool) -> None:
|
|||
def _run_single_hook(
|
||||
classifier: Classifier,
|
||||
hook: Hook,
|
||||
skips: Set[str],
|
||||
skips: set[str],
|
||||
cols: int,
|
||||
diff_before: bytes,
|
||||
verbose: bool,
|
||||
use_color: bool,
|
||||
) -> Tuple[bool, bytes]:
|
||||
) -> tuple[bool, bytes]:
|
||||
filenames = classifier.filenames_for_hook(hook)
|
||||
|
||||
if hook.id in skips or hook.alias in skips:
|
||||
|
@ -271,9 +269,9 @@ def _get_diff() -> bytes:
|
|||
|
||||
|
||||
def _run_hooks(
|
||||
config: Dict[str, Any],
|
||||
config: dict[str, Any],
|
||||
hooks: Sequence[Hook],
|
||||
skips: Set[str],
|
||||
skips: set[str],
|
||||
args: argparse.Namespace,
|
||||
) -> int:
|
||||
"""Actually run the hooks."""
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# determine the latest revision? This adds ~200ms from my tests (and is
|
||||
# significantly faster than https:// or http://). For now, periodically
|
||||
# manually updating the revision is fine.
|
||||
from __future__ import annotations
|
||||
SAMPLE_CONFIG = '''\
|
||||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import os.path
|
||||
from typing import Optional
|
||||
from typing import Tuple
|
||||
|
||||
import pre_commit.constants as C
|
||||
from pre_commit import git
|
||||
|
@ -18,7 +18,7 @@ from pre_commit.xargs import xargs
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _repo_ref(tmpdir: str, repo: str, ref: Optional[str]) -> Tuple[str, str]:
|
||||
def _repo_ref(tmpdir: str, repo: str, ref: str | None) -> tuple[str, str]:
|
||||
# if `ref` is explicitly passed, use it
|
||||
if ref is not None:
|
||||
return repo, ref
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue