diff options
Diffstat (limited to 'pre_commit/commands')
-rw-r--r-- | pre_commit/commands/autoupdate.py | 25 | ||||
-rw-r--r-- | pre_commit/commands/clean.py | 2 | ||||
-rw-r--r-- | pre_commit/commands/gc.py | 11 | ||||
-rw-r--r-- | pre_commit/commands/hook_impl.py | 30 | ||||
-rw-r--r-- | pre_commit/commands/init_templatedir.py | 5 | ||||
-rw-r--r-- | pre_commit/commands/install_uninstall.py | 36 | ||||
-rw-r--r-- | pre_commit/commands/migrate_config.py | 2 | ||||
-rw-r--r-- | pre_commit/commands/run.py | 26 | ||||
-rw-r--r-- | pre_commit/commands/sample_config.py | 1 | ||||
-rw-r--r-- | pre_commit/commands/try_repo.py | 6 |
10 files changed, 80 insertions, 64 deletions
diff --git a/pre_commit/commands/autoupdate.py b/pre_commit/commands/autoupdate.py index 5cb978e..d5352e5 100644 --- a/pre_commit/commands/autoupdate.py +++ b/pre_commit/commands/autoupdate.py @@ -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) diff --git a/pre_commit/commands/clean.py b/pre_commit/commands/clean.py index 2be6c16..5119f64 100644 --- a/pre_commit/commands/clean.py +++ b/pre_commit/commands/clean.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import os.path from pre_commit import output diff --git a/pre_commit/commands/gc.py b/pre_commit/commands/gc.py index 7f6d311..6892e09 100644 --- a/pre_commit/commands/gc.py +++ b/pre_commit/commands/gc.py @@ -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 diff --git a/pre_commit/commands/hook_impl.py b/pre_commit/commands/hook_impl.py index 90bb33b..18e5e9f 100644 --- a/pre_commit/commands/hook_impl.py +++ b/pre_commit/commands/hook_impl.py @@ -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) diff --git a/pre_commit/commands/init_templatedir.py b/pre_commit/commands/init_templatedir.py index 5f17d9c..08af656 100644 --- a/pre_commit/commands/init_templatedir.py +++ b/pre_commit/commands/init_templatedir.py @@ -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( diff --git a/pre_commit/commands/install_uninstall.py b/pre_commit/commands/install_uninstall.py index 50c6443..5ff6cba 100644 --- a/pre_commit/commands/install_uninstall.py +++ b/pre_commit/commands/install_uninstall.py @@ -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 diff --git a/pre_commit/commands/migrate_config.py b/pre_commit/commands/migrate_config.py index fef14cd..c3d0a50 100644 --- a/pre_commit/commands/migrate_config.py +++ b/pre_commit/commands/migrate_config.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import re import textwrap diff --git a/pre_commit/commands/run.py b/pre_commit/commands/run.py index f8ced0f..37f989b 100644 --- a/pre_commit/commands/run.py +++ b/pre_commit/commands/run.py @@ -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.""" diff --git a/pre_commit/commands/sample_config.py b/pre_commit/commands/sample_config.py index 64617c3..82a1617 100644 --- a/pre_commit/commands/sample_config.py +++ b/pre_commit/commands/sample_config.py @@ -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 diff --git a/pre_commit/commands/try_repo.py b/pre_commit/commands/try_repo.py index 4aee209..ef099f5 100644 --- a/pre_commit/commands/try_repo.py +++ b/pre_commit/commands/try_repo.py @@ -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 |