mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-02-17 00:04:42 +04:00
Some manual .format() -> f-strings
This commit is contained in:
parent
aefbe71765
commit
9000e9dd41
27 changed files with 133 additions and 173 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
import argparse
|
import argparse
|
||||||
import functools
|
import functools
|
||||||
import logging
|
import logging
|
||||||
import pipes
|
import shlex
|
||||||
import sys
|
import sys
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
@ -25,18 +25,17 @@ check_string_regex = cfgv.check_and(cfgv.check_string, cfgv.check_regex)
|
||||||
def check_type_tag(tag: str) -> None:
|
def check_type_tag(tag: str) -> None:
|
||||||
if tag not in ALL_TAGS:
|
if tag not in ALL_TAGS:
|
||||||
raise cfgv.ValidationError(
|
raise cfgv.ValidationError(
|
||||||
'Type tag {!r} is not recognized. '
|
f'Type tag {tag!r} is not recognized. '
|
||||||
'Try upgrading identify and pre-commit?'.format(tag),
|
f'Try upgrading identify and pre-commit?',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def check_min_version(version: str) -> None:
|
def check_min_version(version: str) -> None:
|
||||||
if parse_version(version) > parse_version(C.VERSION):
|
if parse_version(version) > parse_version(C.VERSION):
|
||||||
raise cfgv.ValidationError(
|
raise cfgv.ValidationError(
|
||||||
'pre-commit version {} is required but version {} is installed. '
|
f'pre-commit version {version} is required but version '
|
||||||
'Perhaps run `pip install --upgrade pre-commit`.'.format(
|
f'{C.VERSION} is installed. '
|
||||||
version, C.VERSION,
|
f'Perhaps run `pip install --upgrade pre-commit`.',
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -142,9 +141,7 @@ def _entry(modname: str) -> str:
|
||||||
runner, so to prevent issues with spaces and backslashes (on Windows)
|
runner, so to prevent issues with spaces and backslashes (on Windows)
|
||||||
it must be quoted here.
|
it must be quoted here.
|
||||||
"""
|
"""
|
||||||
return '{} -m pre_commit.meta_hooks.{}'.format(
|
return f'{shlex.quote(sys.executable)} -m pre_commit.meta_hooks.{modname}'
|
||||||
pipes.quote(sys.executable), modname,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def warn_unknown_keys_root(
|
def warn_unknown_keys_root(
|
||||||
|
|
@ -152,9 +149,7 @@ def warn_unknown_keys_root(
|
||||||
orig_keys: Sequence[str],
|
orig_keys: Sequence[str],
|
||||||
dct: Dict[str, str],
|
dct: Dict[str, str],
|
||||||
) -> None:
|
) -> None:
|
||||||
logger.warning(
|
logger.warning(f'Unexpected key(s) present at root: {", ".join(extra)}')
|
||||||
'Unexpected key(s) present at root: {}'.format(', '.join(extra)),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def warn_unknown_keys_repo(
|
def warn_unknown_keys_repo(
|
||||||
|
|
@ -163,9 +158,7 @@ def warn_unknown_keys_repo(
|
||||||
dct: Dict[str, str],
|
dct: Dict[str, str],
|
||||||
) -> None:
|
) -> None:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
'Unexpected key(s) present on {}: {}'.format(
|
f'Unexpected key(s) present on {dct["repo"]}: {", ".join(extra)}',
|
||||||
dct['repo'], ', '.join(extra),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -80,13 +80,12 @@ def _check_hooks_still_exist_at_rev(
|
||||||
hooks_missing = hooks - {hook['id'] for hook in manifest}
|
hooks_missing = hooks - {hook['id'] for hook in manifest}
|
||||||
if hooks_missing:
|
if hooks_missing:
|
||||||
raise RepositoryCannotBeUpdatedError(
|
raise RepositoryCannotBeUpdatedError(
|
||||||
'Cannot update because the tip of master is missing these hooks:\n'
|
f'Cannot update because the tip of HEAD is missing these hooks:\n'
|
||||||
'{}'.format(', '.join(sorted(hooks_missing))),
|
f'{", ".join(sorted(hooks_missing))}',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
REV_LINE_FMT = '{}rev:{}{}{}{}'
|
|
||||||
|
|
||||||
|
|
||||||
def _original_lines(
|
def _original_lines(
|
||||||
|
|
@ -126,9 +125,7 @@ def _write_new_config(path: str, rev_infos: List[Optional[RevInfo]]) -> None:
|
||||||
comment = ''
|
comment = ''
|
||||||
else:
|
else:
|
||||||
comment = match.group(4)
|
comment = match.group(4)
|
||||||
lines[idx] = REV_LINE_FMT.format(
|
lines[idx] = f'{match[1]}rev:{match[2]}{new_rev}{comment}{match[5]}'
|
||||||
match.group(1), match.group(2), new_rev, comment, match.group(5),
|
|
||||||
)
|
|
||||||
|
|
||||||
with open(path, 'w') as f:
|
with open(path, 'w') as f:
|
||||||
f.write(''.join(lines))
|
f.write(''.join(lines))
|
||||||
|
|
|
||||||
|
|
@ -89,8 +89,8 @@ def _install_hook_script(
|
||||||
os.remove(legacy_path)
|
os.remove(legacy_path)
|
||||||
elif os.path.exists(legacy_path):
|
elif os.path.exists(legacy_path):
|
||||||
output.write_line(
|
output.write_line(
|
||||||
'Running in migration mode with existing hooks at {}\n'
|
f'Running in migration mode with existing hooks at {legacy_path}\n'
|
||||||
'Use -f to use only pre-commit.'.format(legacy_path),
|
f'Use -f to use only pre-commit.',
|
||||||
)
|
)
|
||||||
|
|
||||||
params = {
|
params = {
|
||||||
|
|
@ -110,7 +110,7 @@ def _install_hook_script(
|
||||||
hook_file.write(before + TEMPLATE_START)
|
hook_file.write(before + TEMPLATE_START)
|
||||||
for line in to_template.splitlines():
|
for line in to_template.splitlines():
|
||||||
var = line.split()[0]
|
var = line.split()[0]
|
||||||
hook_file.write('{} = {!r}\n'.format(var, params[var]))
|
hook_file.write(f'{var} = {params[var]!r}\n')
|
||||||
hook_file.write(TEMPLATE_END + after)
|
hook_file.write(TEMPLATE_END + after)
|
||||||
make_executable(hook_path)
|
make_executable(hook_path)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -243,9 +243,10 @@ def _run_hooks(
|
||||||
output.write_line('All changes made by hooks:')
|
output.write_line('All changes made by hooks:')
|
||||||
# args.color is a boolean.
|
# args.color is a boolean.
|
||||||
# See user_color function in color.py
|
# See user_color function in color.py
|
||||||
|
git_color_opt = 'always' if args.color else 'never'
|
||||||
subprocess.call((
|
subprocess.call((
|
||||||
'git', '--no-pager', 'diff', '--no-ext-diff',
|
'git', '--no-pager', 'diff', '--no-ext-diff',
|
||||||
'--color={}'.format({True: 'always', False: 'never'}[args.color]),
|
f'--color={git_color_opt}',
|
||||||
))
|
))
|
||||||
|
|
||||||
return retval
|
return retval
|
||||||
|
|
@ -282,8 +283,8 @@ def run(
|
||||||
return 1
|
return 1
|
||||||
if _has_unstaged_config(config_file) and not no_stash:
|
if _has_unstaged_config(config_file) and not no_stash:
|
||||||
logger.error(
|
logger.error(
|
||||||
'Your pre-commit configuration is unstaged.\n'
|
f'Your pre-commit configuration is unstaged.\n'
|
||||||
'`git add {}` to fix this.'.format(config_file),
|
f'`git add {config_file}` to fix this.',
|
||||||
)
|
)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
@ -308,9 +309,7 @@ def run(
|
||||||
|
|
||||||
if args.hook and not hooks:
|
if args.hook and not hooks:
|
||||||
output.write_line(
|
output.write_line(
|
||||||
'No hook with id `{}` in stage `{}`'.format(
|
f'No hook with id `{args.hook}` in stage `{args.hook_stage}`',
|
||||||
args.hook, args.hook_stage,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -183,13 +183,11 @@ def check_for_cygwin_mismatch() -> None:
|
||||||
if is_cygwin_python ^ is_cygwin_git:
|
if is_cygwin_python ^ is_cygwin_git:
|
||||||
exe_type = {True: '(cygwin)', False: '(windows)'}
|
exe_type = {True: '(cygwin)', False: '(windows)'}
|
||||||
logger.warn(
|
logger.warn(
|
||||||
'pre-commit has detected a mix of cygwin python / git\n'
|
f'pre-commit has detected a mix of cygwin python / git\n'
|
||||||
'This combination is not supported, it is likely you will '
|
f'This combination is not supported, it is likely you will '
|
||||||
'receive an error later in the program.\n'
|
f'receive an error later in the program.\n'
|
||||||
'Make sure to use cygwin git+python while using cygwin\n'
|
f'Make sure to use cygwin git+python while using cygwin\n'
|
||||||
'These can be installed through the cygwin installer.\n'
|
f'These can be installed through the cygwin installer.\n'
|
||||||
' - python {}\n'
|
f' - python {exe_type[is_cygwin_python]}\n'
|
||||||
' - git {}\n'.format(
|
f' - git {exe_type[is_cygwin_git]}\n',
|
||||||
exe_type[is_cygwin_python], exe_type[is_cygwin_git],
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ def install_environment(
|
||||||
|
|
||||||
def get_docker_user() -> str: # pragma: windows no cover
|
def get_docker_user() -> str: # pragma: windows no cover
|
||||||
try:
|
try:
|
||||||
return '{}:{}'.format(os.getuid(), os.getgid())
|
return f'{os.getuid()}:{os.getgid()}'
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return '1000:1000'
|
return '1000:1000'
|
||||||
|
|
||||||
|
|
@ -94,7 +94,7 @@ def docker_cmd() -> Tuple[str, ...]: # pragma: windows no cover
|
||||||
# https://docs.docker.com/engine/reference/commandline/run/#mount-volumes-from-container-volumes-from
|
# 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
|
# The `Z` option tells Docker to label the content with a private
|
||||||
# unshared label. Only the current container can use a private volume.
|
# unshared label. Only the current container can use a private volume.
|
||||||
'-v', '{}:/src:rw,Z'.format(os.getcwd()),
|
'-v', f'{os.getcwd()}:/src:rw,Z',
|
||||||
'--workdir', '/src',
|
'--workdir', '/src',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,8 @@ def assert_no_additional_deps(
|
||||||
) -> None:
|
) -> None:
|
||||||
if additional_deps:
|
if additional_deps:
|
||||||
raise AssertionError(
|
raise AssertionError(
|
||||||
'For now, pre-commit does not support '
|
f'For now, pre-commit does not support '
|
||||||
'additional_dependencies for {}'.format(lang),
|
f'additional_dependencies for {lang}',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ def _envdir(prefix: Prefix, version: str) -> str:
|
||||||
def get_env_patch(venv: str) -> PatchesT: # pragma: windows no cover
|
def get_env_patch(venv: str) -> PatchesT: # pragma: windows no cover
|
||||||
if sys.platform == 'cygwin': # pragma: no cover
|
if sys.platform == 'cygwin': # pragma: no cover
|
||||||
_, win_venv, _ = cmd_output('cygpath', '-w', venv)
|
_, win_venv, _ = cmd_output('cygpath', '-w', venv)
|
||||||
install_prefix = r'{}\bin'.format(win_venv.strip())
|
install_prefix = fr'{win_venv.strip()}\bin'
|
||||||
lib_dir = 'lib'
|
lib_dir = 'lib'
|
||||||
elif sys.platform == 'win32': # pragma: no cover
|
elif sys.platform == 'win32': # pragma: no cover
|
||||||
install_prefix = bin_dir(venv)
|
install_prefix = bin_dir(venv)
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ def _process_filename_at_once(pattern: Pattern[bytes], filename: str) -> int:
|
||||||
if match:
|
if match:
|
||||||
retv = 1
|
retv = 1
|
||||||
line_no = contents[:match.start()].count(b'\n')
|
line_no = contents[:match.start()].count(b'\n')
|
||||||
output.write('{}:{}:'.format(filename, line_no + 1))
|
output.write(f'{filename}:{line_no + 1}:')
|
||||||
|
|
||||||
matched_lines = match.group().split(b'\n')
|
matched_lines = match.group().split(b'\n')
|
||||||
matched_lines[0] = contents.split(b'\n')[line_no]
|
matched_lines[0] = contents.split(b'\n')[line_no]
|
||||||
|
|
|
||||||
|
|
@ -47,10 +47,10 @@ def _find_by_py_launcher(
|
||||||
version: str,
|
version: str,
|
||||||
) -> Optional[str]: # pragma: no cover (windows only)
|
) -> Optional[str]: # pragma: no cover (windows only)
|
||||||
if version.startswith('python'):
|
if version.startswith('python'):
|
||||||
|
num = version[len('python'):]
|
||||||
try:
|
try:
|
||||||
return cmd_output(
|
return cmd_output(
|
||||||
'py', '-{}'.format(version[len('python'):]),
|
'py', f'-{num}', '-c', 'import sys; print(sys.executable)',
|
||||||
'-c', 'import sys; print(sys.executable)',
|
|
||||||
)[1].strip()
|
)[1].strip()
|
||||||
except CalledProcessError:
|
except CalledProcessError:
|
||||||
pass
|
pass
|
||||||
|
|
@ -88,7 +88,7 @@ def get_default_version() -> str: # pragma: no cover (platform dependent)
|
||||||
return exe
|
return exe
|
||||||
|
|
||||||
# Next try the `pythonX.X` executable
|
# Next try the `pythonX.X` executable
|
||||||
exe = 'python{}.{}'.format(*sys.version_info)
|
exe = f'python{sys.version_info[0]}.{sys.version_info[1]}'
|
||||||
if find_executable(exe):
|
if find_executable(exe):
|
||||||
return exe
|
return exe
|
||||||
|
|
||||||
|
|
@ -96,7 +96,8 @@ def get_default_version() -> str: # pragma: no cover (platform dependent)
|
||||||
return exe
|
return exe
|
||||||
|
|
||||||
# Give a best-effort try for windows
|
# Give a best-effort try for windows
|
||||||
if os.path.exists(r'C:\{}\python.exe'.format(exe.replace('.', ''))):
|
default_folder_name = exe.replace('.', '')
|
||||||
|
if os.path.exists(fr'C:\{default_folder_name}\python.exe'):
|
||||||
return exe
|
return exe
|
||||||
|
|
||||||
# We tried!
|
# We tried!
|
||||||
|
|
@ -135,7 +136,8 @@ def norm_version(version: str) -> str:
|
||||||
# If it is in the form pythonx.x search in the default
|
# If it is in the form pythonx.x search in the default
|
||||||
# place on windows
|
# place on windows
|
||||||
if version.startswith('python'):
|
if version.startswith('python'):
|
||||||
return r'C:\{}\python.exe'.format(version.replace('.', ''))
|
default_folder_name = version.replace('.', '')
|
||||||
|
return fr'C:\{default_folder_name}\python.exe'
|
||||||
|
|
||||||
# Otherwise assume it is a path
|
# Otherwise assume it is a path
|
||||||
return os.path.expanduser(version)
|
return os.path.expanduser(version)
|
||||||
|
|
|
||||||
|
|
@ -21,16 +21,12 @@ class LoggingHandler(logging.Handler):
|
||||||
self.use_color = use_color
|
self.use_color = use_color
|
||||||
|
|
||||||
def emit(self, record: logging.LogRecord) -> None:
|
def emit(self, record: logging.LogRecord) -> None:
|
||||||
output.write_line(
|
level_msg = color.format_color(
|
||||||
'{} {}'.format(
|
f'[{record.levelname}]',
|
||||||
color.format_color(
|
LOG_LEVEL_COLORS[record.levelname],
|
||||||
f'[{record.levelname}]',
|
self.use_color,
|
||||||
LOG_LEVEL_COLORS[record.levelname],
|
|
||||||
self.use_color,
|
|
||||||
),
|
|
||||||
record.getMessage(),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
output.write_line(f'{level_msg} {record.getMessage()}')
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,7 @@ def check_useless_excludes(config_file: str) -> int:
|
||||||
exclude = config['exclude']
|
exclude = config['exclude']
|
||||||
if not exclude_matches_any(classifier.filenames, '', exclude):
|
if not exclude_matches_any(classifier.filenames, '', exclude):
|
||||||
print(
|
print(
|
||||||
'The global exclude pattern {!r} does not match any files'
|
f'The global exclude pattern {exclude!r} does not match any files',
|
||||||
.format(exclude),
|
|
||||||
)
|
)
|
||||||
retv = 1
|
retv = 1
|
||||||
|
|
||||||
|
|
@ -50,8 +49,8 @@ def check_useless_excludes(config_file: str) -> int:
|
||||||
include, exclude = hook['files'], hook['exclude']
|
include, exclude = hook['files'], hook['exclude']
|
||||||
if not exclude_matches_any(names, include, exclude):
|
if not exclude_matches_any(names, include, exclude):
|
||||||
print(
|
print(
|
||||||
'The exclude pattern {!r} for {} does not match any files'
|
f'The exclude pattern {exclude!r} for {hook["id"]} does '
|
||||||
.format(exclude, hook['id']),
|
f'not match any files',
|
||||||
)
|
)
|
||||||
retv = 1
|
retv = 1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,12 +54,9 @@ def get_hook_message(
|
||||||
assert end_msg is not None
|
assert end_msg is not None
|
||||||
assert end_color is not None
|
assert end_color is not None
|
||||||
assert use_color is not None
|
assert use_color is not None
|
||||||
return '{}{}{}{}\n'.format(
|
dots = '.' * (cols - len(start) - len(postfix) - len(end_msg) - 1)
|
||||||
start,
|
end = color.format_color(end_msg, end_color, use_color)
|
||||||
'.' * (cols - len(start) - len(postfix) - len(end_msg) - 1),
|
return f'{start}{dots}{postfix}{end}\n'
|
||||||
postfix,
|
|
||||||
color.format_color(end_msg, end_color, use_color),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def write(s: str, stream: IO[bytes] = sys.stdout.buffer) -> None:
|
def write(s: str, stream: IO[bytes] = sys.stdout.buffer) -> None:
|
||||||
|
|
|
||||||
|
|
@ -137,8 +137,8 @@ class Hook(NamedTuple):
|
||||||
extra_keys = set(dct) - set(_KEYS)
|
extra_keys = set(dct) - set(_KEYS)
|
||||||
if extra_keys:
|
if extra_keys:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
'Unexpected key(s) present on {} => {}: '
|
f'Unexpected key(s) present on {src} => {dct["id"]}: '
|
||||||
'{}'.format(src, dct['id'], ', '.join(sorted(extra_keys))),
|
f'{", ".join(sorted(extra_keys))}',
|
||||||
)
|
)
|
||||||
return cls(src=src, prefix=prefix, **{k: dct[k] for k in _KEYS})
|
return cls(src=src, prefix=prefix, **{k: dct[k] for k in _KEYS})
|
||||||
|
|
||||||
|
|
@ -154,11 +154,9 @@ def _hook(
|
||||||
version = ret['minimum_pre_commit_version']
|
version = ret['minimum_pre_commit_version']
|
||||||
if parse_version(version) > parse_version(C.VERSION):
|
if parse_version(version) > parse_version(C.VERSION):
|
||||||
logger.error(
|
logger.error(
|
||||||
'The hook `{}` requires pre-commit version {} but version {} '
|
f'The hook `{ret["id"]}` requires pre-commit version {version} '
|
||||||
'is installed. '
|
f'but version {C.VERSION} is installed. '
|
||||||
'Perhaps run `pip install --upgrade pre-commit`.'.format(
|
f'Perhaps run `pip install --upgrade pre-commit`.',
|
||||||
ret['id'], version, C.VERSION,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
|
@ -210,10 +208,9 @@ def _cloned_repository_hooks(
|
||||||
for hook in repo_config['hooks']:
|
for hook in repo_config['hooks']:
|
||||||
if hook['id'] not in by_id:
|
if hook['id'] not in by_id:
|
||||||
logger.error(
|
logger.error(
|
||||||
'`{}` is not present in repository {}. '
|
f'`{hook["id"]}` is not present in repository {repo}. '
|
||||||
'Typo? Perhaps it is introduced in a newer version? '
|
f'Typo? Perhaps it is introduced in a newer version? '
|
||||||
'Often `pre-commit autoupdate` fixes this.'
|
f'Often `pre-commit autoupdate` fixes this.',
|
||||||
.format(hook['id'], repo),
|
|
||||||
)
|
)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,12 +52,11 @@ def _norm_exe(exe: str) -> Tuple[str, ...]:
|
||||||
def _run_legacy() -> Tuple[int, bytes]:
|
def _run_legacy() -> Tuple[int, bytes]:
|
||||||
if __file__.endswith('.legacy'):
|
if __file__.endswith('.legacy'):
|
||||||
raise SystemExit(
|
raise SystemExit(
|
||||||
"bug: pre-commit's script is installed in migration mode\n"
|
f"bug: pre-commit's script is installed in migration mode\n"
|
||||||
'run `pre-commit install -f --hook-type {}` to fix this\n\n'
|
f'run `pre-commit install -f --hook-type {HOOK_TYPE}` to fix '
|
||||||
'Please report this bug at '
|
f'this\n\n'
|
||||||
'https://github.com/pre-commit/pre-commit/issues'.format(
|
f'Please report this bug at '
|
||||||
HOOK_TYPE,
|
f'https://github.com/pre-commit/pre-commit/issues',
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if HOOK_TYPE == 'pre-push':
|
if HOOK_TYPE == 'pre-push':
|
||||||
|
|
@ -82,20 +81,17 @@ def _validate_config() -> None:
|
||||||
if os.path.isfile(cfg):
|
if os.path.isfile(cfg):
|
||||||
pass
|
pass
|
||||||
elif SKIP_ON_MISSING_CONFIG or os.getenv('PRE_COMMIT_ALLOW_NO_CONFIG'):
|
elif SKIP_ON_MISSING_CONFIG or os.getenv('PRE_COMMIT_ALLOW_NO_CONFIG'):
|
||||||
print(
|
print(f'`{CONFIG}` config file not found. Skipping `pre-commit`.')
|
||||||
'`{}` config file not found. '
|
|
||||||
'Skipping `pre-commit`.'.format(CONFIG),
|
|
||||||
)
|
|
||||||
raise EarlyExit()
|
raise EarlyExit()
|
||||||
else:
|
else:
|
||||||
raise FatalError(
|
raise FatalError(
|
||||||
'No {} file was found\n'
|
f'No {CONFIG} file was found\n'
|
||||||
'- To temporarily silence this, run '
|
f'- To temporarily silence this, run '
|
||||||
'`PRE_COMMIT_ALLOW_NO_CONFIG=1 git ...`\n'
|
f'`PRE_COMMIT_ALLOW_NO_CONFIG=1 git ...`\n'
|
||||||
'- To permanently silence this, install pre-commit with the '
|
f'- To permanently silence this, install pre-commit with the '
|
||||||
'--allow-missing-config option\n'
|
f'--allow-missing-config option\n'
|
||||||
'- To uninstall pre-commit run '
|
f'- To uninstall pre-commit run '
|
||||||
'`pre-commit uninstall`'.format(CONFIG),
|
f'`pre-commit uninstall`',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ def _unstaged_changes_cleared(patch_dir: str) -> Generator[None, None, None]:
|
||||||
retcode=None,
|
retcode=None,
|
||||||
)
|
)
|
||||||
if retcode and diff_stdout_binary.strip():
|
if retcode and diff_stdout_binary.strip():
|
||||||
patch_filename = 'patch{}'.format(int(time.time()))
|
patch_filename = f'patch{int(time.time())}'
|
||||||
patch_filename = os.path.join(patch_dir, patch_filename)
|
patch_filename = os.path.join(patch_dir, patch_filename)
|
||||||
logger.warning('Unstaged files detected.')
|
logger.warning('Unstaged files detected.')
|
||||||
logger.info(
|
logger.info(
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ class Store:
|
||||||
@classmethod
|
@classmethod
|
||||||
def db_repo_name(cls, repo: str, deps: Sequence[str]) -> str:
|
def db_repo_name(cls, repo: str, deps: Sequence[str]) -> str:
|
||||||
if deps:
|
if deps:
|
||||||
return '{}:{}'.format(repo, ','.join(sorted(deps)))
|
return f'{repo}:{",".join(sorted(deps))}'
|
||||||
else:
|
else:
|
||||||
return repo
|
return repo
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -105,11 +105,9 @@ class CalledProcessError(RuntimeError):
|
||||||
return b' (none)'
|
return b' (none)'
|
||||||
|
|
||||||
return b''.join((
|
return b''.join((
|
||||||
'command: {!r}\n'
|
f'command: {self.cmd!r}\n'.encode(),
|
||||||
'return code: {}\n'
|
f'return code: {self.returncode}\n'.encode(),
|
||||||
'expected return code: {}\n'.format(
|
f'expected return code: {self.expected_returncode}\n'.encode(),
|
||||||
self.cmd, self.returncode, self.expected_returncode,
|
|
||||||
).encode(),
|
|
||||||
b'stdout:', _indent_or_none(self.stdout), b'\n',
|
b'stdout:', _indent_or_none(self.stdout), b'\n',
|
||||||
b'stderr:', _indent_or_none(self.stderr),
|
b'stderr:', _indent_or_none(self.stderr),
|
||||||
))
|
))
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env bash
|
||||||
import sys
|
echo 0
|
||||||
|
echo 1 1>&2
|
||||||
|
echo 2
|
||||||
def main():
|
echo 3 1>&2
|
||||||
for i in range(6):
|
echo 4
|
||||||
f = sys.stdout if i % 2 == 0 else sys.stderr
|
echo 5 1>&2
|
||||||
f.write(f'{i}\n')
|
|
||||||
f.flush()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
exit(main())
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env bash
|
||||||
import sys
|
t() {
|
||||||
|
if [ -t "$1" ]; then
|
||||||
|
echo "$2: True"
|
||||||
def main():
|
else
|
||||||
print('stdin: {}'.format(sys.stdin.isatty()))
|
echo "$2: False"
|
||||||
print('stdout: {}'.format(sys.stdout.isatty()))
|
fi
|
||||||
print('stderr: {}'.format(sys.stderr.isatty()))
|
}
|
||||||
|
t 0 stdin
|
||||||
|
t 1 stdout
|
||||||
if __name__ == '__main__':
|
t 2 stderr
|
||||||
exit(main())
|
|
||||||
|
|
|
||||||
|
|
@ -291,13 +291,11 @@ def test_minimum_pre_commit_version_failing():
|
||||||
cfg = {'repos': [], 'minimum_pre_commit_version': '999'}
|
cfg = {'repos': [], 'minimum_pre_commit_version': '999'}
|
||||||
cfgv.validate(cfg, CONFIG_SCHEMA)
|
cfgv.validate(cfg, CONFIG_SCHEMA)
|
||||||
assert str(excinfo.value) == (
|
assert str(excinfo.value) == (
|
||||||
'\n'
|
f'\n'
|
||||||
'==> At Config()\n'
|
f'==> At Config()\n'
|
||||||
'==> At key: minimum_pre_commit_version\n'
|
f'==> At key: minimum_pre_commit_version\n'
|
||||||
'=====> pre-commit version 999 is required but version {} is '
|
f'=====> pre-commit version 999 is required but version {C.VERSION} '
|
||||||
'installed. Perhaps run `pip install --upgrade pre-commit`.'.format(
|
f'is installed. Perhaps run `pip install --upgrade pre-commit`.'
|
||||||
C.VERSION,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import pipes
|
import shlex
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
@ -118,12 +118,12 @@ def test_rev_info_update_does_not_freeze_if_already_sha(out_of_date):
|
||||||
|
|
||||||
def test_autoupdate_up_to_date_repo(up_to_date, tmpdir, store):
|
def test_autoupdate_up_to_date_repo(up_to_date, tmpdir, store):
|
||||||
contents = (
|
contents = (
|
||||||
'repos:\n'
|
f'repos:\n'
|
||||||
'- repo: {}\n'
|
f'- repo: {up_to_date}\n'
|
||||||
' rev: {}\n'
|
f' rev: {git.head_rev(up_to_date)}\n'
|
||||||
' hooks:\n'
|
f' hooks:\n'
|
||||||
' - id: foo\n'
|
f' - id: foo\n'
|
||||||
).format(up_to_date, git.head_rev(up_to_date))
|
)
|
||||||
cfg = tmpdir.join(C.CONFIG_FILE)
|
cfg = tmpdir.join(C.CONFIG_FILE)
|
||||||
cfg.write(contents)
|
cfg.write(contents)
|
||||||
|
|
||||||
|
|
@ -278,7 +278,7 @@ def test_loses_formatting_when_not_detectable(out_of_date, store, tmpdir):
|
||||||
' ],\n'
|
' ],\n'
|
||||||
' }}\n'
|
' }}\n'
|
||||||
']\n'.format(
|
']\n'.format(
|
||||||
pipes.quote(out_of_date.path), out_of_date.original_rev,
|
shlex.quote(out_of_date.path), out_of_date.original_rev,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
cfg = tmpdir.join(C.CONFIG_FILE)
|
cfg = tmpdir.join(C.CONFIG_FILE)
|
||||||
|
|
@ -286,12 +286,12 @@ def test_loses_formatting_when_not_detectable(out_of_date, store, tmpdir):
|
||||||
|
|
||||||
assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 0
|
assert autoupdate(str(cfg), store, freeze=False, tags_only=False) == 0
|
||||||
expected = (
|
expected = (
|
||||||
'repos:\n'
|
f'repos:\n'
|
||||||
'- repo: {}\n'
|
f'- repo: {out_of_date.path}\n'
|
||||||
' rev: {}\n'
|
f' rev: {out_of_date.head_rev}\n'
|
||||||
' hooks:\n'
|
f' hooks:\n'
|
||||||
' - id: foo\n'
|
f' - id: foo\n'
|
||||||
).format(out_of_date.path, out_of_date.head_rev)
|
)
|
||||||
assert cfg.read() == expected
|
assert cfg.read() == expected
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -358,12 +358,12 @@ def test_hook_disppearing_repo_raises(hook_disappearing, store):
|
||||||
|
|
||||||
def test_autoupdate_hook_disappearing_repo(hook_disappearing, tmpdir, store):
|
def test_autoupdate_hook_disappearing_repo(hook_disappearing, tmpdir, store):
|
||||||
contents = (
|
contents = (
|
||||||
'repos:\n'
|
f'repos:\n'
|
||||||
'- repo: {}\n'
|
f'- repo: {hook_disappearing.path}\n'
|
||||||
' rev: {}\n'
|
f' rev: {hook_disappearing.original_rev}\n'
|
||||||
' hooks:\n'
|
f' hooks:\n'
|
||||||
' - id: foo\n'
|
f' - id: foo\n'
|
||||||
).format(hook_disappearing.path, hook_disappearing.original_rev)
|
)
|
||||||
cfg = tmpdir.join(C.CONFIG_FILE)
|
cfg = tmpdir.join(C.CONFIG_FILE)
|
||||||
cfg.write(contents)
|
cfg.write(contents)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,11 +52,11 @@ def test_shebang_posix_not_on_path():
|
||||||
|
|
||||||
|
|
||||||
def test_shebang_posix_on_path(tmpdir):
|
def test_shebang_posix_on_path(tmpdir):
|
||||||
tmpdir.join('python{}'.format(sys.version_info[0])).ensure()
|
tmpdir.join(f'python{sys.version_info[0]}').ensure()
|
||||||
|
|
||||||
with mock.patch.object(sys, 'platform', 'posix'):
|
with mock.patch.object(sys, 'platform', 'posix'):
|
||||||
with mock.patch.object(os, 'defpath', tmpdir.strpath):
|
with mock.patch.object(os, 'defpath', tmpdir.strpath):
|
||||||
expected = '#!/usr/bin/env python{}'.format(sys.version_info[0])
|
expected = f'#!/usr/bin/env python{sys.version_info[0]}'
|
||||||
assert shebang() == expected
|
assert shebang() == expected
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import os.path
|
import os.path
|
||||||
import pipes
|
import shlex
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
@ -580,8 +580,7 @@ def test_lots_of_files(store, tempdir_factory):
|
||||||
|
|
||||||
# Write a crap ton of files
|
# Write a crap ton of files
|
||||||
for i in range(400):
|
for i in range(400):
|
||||||
filename = '{}{}'.format('a' * 100, i)
|
open(f'{"a" * 100}{i}', 'w').close()
|
||||||
open(filename, 'w').close()
|
|
||||||
|
|
||||||
cmd_output('git', 'add', '.')
|
cmd_output('git', 'add', '.')
|
||||||
install(C.CONFIG_FILE, store, hook_types=['pre-commit'])
|
install(C.CONFIG_FILE, store, hook_types=['pre-commit'])
|
||||||
|
|
@ -673,7 +672,7 @@ def test_local_hook_passes(cap_out, store, repo_with_passing_hook):
|
||||||
'id': 'identity-copy',
|
'id': 'identity-copy',
|
||||||
'name': 'identity-copy',
|
'name': 'identity-copy',
|
||||||
'entry': '{} -m pre_commit.meta_hooks.identity'.format(
|
'entry': '{} -m pre_commit.meta_hooks.identity'.format(
|
||||||
pipes.quote(sys.executable),
|
shlex.quote(sys.executable),
|
||||||
),
|
),
|
||||||
'language': 'system',
|
'language': 'system',
|
||||||
'files': r'\.py$',
|
'files': r'\.py$',
|
||||||
|
|
@ -893,7 +892,7 @@ def test_args_hook_only(cap_out, store, repo_with_passing_hook):
|
||||||
'id': 'identity-copy',
|
'id': 'identity-copy',
|
||||||
'name': 'identity-copy',
|
'name': 'identity-copy',
|
||||||
'entry': '{} -m pre_commit.meta_hooks.identity'.format(
|
'entry': '{} -m pre_commit.meta_hooks.identity'.format(
|
||||||
pipes.quote(sys.executable),
|
shlex.quote(sys.executable),
|
||||||
),
|
),
|
||||||
'language': 'system',
|
'language': 'system',
|
||||||
'files': r'\.py$',
|
'files': r'\.py$',
|
||||||
|
|
|
||||||
|
|
@ -99,9 +99,7 @@ def test_log_and_exit(cap_out, mock_store_dir):
|
||||||
|
|
||||||
printed = cap_out.get()
|
printed = cap_out.get()
|
||||||
log_file = os.path.join(mock_store_dir, 'pre-commit.log')
|
log_file = os.path.join(mock_store_dir, 'pre-commit.log')
|
||||||
assert printed == (
|
assert printed == f'msg: FatalError: hai\nCheck the log at {log_file}\n'
|
||||||
'msg: FatalError: hai\n' 'Check the log at {}\n'.format(log_file)
|
|
||||||
)
|
|
||||||
|
|
||||||
assert os.path.exists(log_file)
|
assert os.path.exists(log_file)
|
||||||
with open(log_file) as f:
|
with open(log_file) as f:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import os.path
|
import os.path
|
||||||
import pipes
|
import shlex
|
||||||
|
|
||||||
from pre_commit.languages.ruby import _install_rbenv
|
from pre_commit.languages.ruby import _install_rbenv
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
|
|
@ -21,7 +21,7 @@ def test_install_rbenv(tempdir_factory):
|
||||||
cmd_output(
|
cmd_output(
|
||||||
'bash', '-c',
|
'bash', '-c',
|
||||||
'. {} && rbenv --help'.format(
|
'. {} && rbenv --help'.format(
|
||||||
pipes.quote(prefix.path('rbenv-default', 'bin', 'activate')),
|
shlex.quote(prefix.path('rbenv-default', 'bin', 'activate')),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -35,6 +35,6 @@ def test_install_rbenv_with_version(tempdir_factory):
|
||||||
cmd_output(
|
cmd_output(
|
||||||
'bash', '-c',
|
'bash', '-c',
|
||||||
'. {} && rbenv install --help'.format(
|
'. {} && rbenv install --help'.format(
|
||||||
pipes.quote(prefix.path('rbenv-1.9.3p547', 'bin', 'activate')),
|
shlex.quote(prefix.path('rbenv-1.9.3p547', 'bin', 'activate')),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -805,9 +805,9 @@ def test_hook_id_not_present(tempdir_factory, store, fake_log_handler):
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
_get_hook(config, store, 'i-dont-exist')
|
_get_hook(config, store, 'i-dont-exist')
|
||||||
assert fake_log_handler.handle.call_args[0][0].msg == (
|
assert fake_log_handler.handle.call_args[0][0].msg == (
|
||||||
'`i-dont-exist` is not present in repository file://{}. '
|
f'`i-dont-exist` is not present in repository file://{path}. '
|
||||||
'Typo? Perhaps it is introduced in a newer version? '
|
f'Typo? Perhaps it is introduced in a newer version? '
|
||||||
'Often `pre-commit autoupdate` fixes this.'.format(path)
|
f'Often `pre-commit autoupdate` fixes this.'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue