Merge pull request #1544 from pre-commit/wip_warning_on_old_config_style

warn on old list-style configuration
This commit is contained in:
Anthony Sottile 2020-07-25 14:27:08 -07:00 committed by GitHub
commit 4f5cb99ff5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 59 additions and 40 deletions

View file

@ -12,8 +12,10 @@ import cfgv
from identify.identify import ALL_TAGS from identify.identify import ALL_TAGS
import pre_commit.constants as C import pre_commit.constants as C
from pre_commit.color import add_color_option
from pre_commit.error_handler import FatalError from pre_commit.error_handler import FatalError
from pre_commit.languages.all import all_languages from pre_commit.languages.all import all_languages
from pre_commit.logging_handler import logging_handler
from pre_commit.util import parse_version from pre_commit.util import parse_version
from pre_commit.util import yaml_load from pre_commit.util import yaml_load
@ -43,6 +45,7 @@ def _make_argparser(filenames_help: str) -> argparse.ArgumentParser:
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*', help=filenames_help) parser.add_argument('filenames', nargs='*', help=filenames_help)
parser.add_argument('-V', '--version', action='version', version=C.VERSION) parser.add_argument('-V', '--version', action='version', version=C.VERSION)
add_color_option(parser)
return parser return parser
@ -92,6 +95,8 @@ load_manifest = functools.partial(
def validate_manifest_main(argv: Optional[Sequence[str]] = None) -> int: def validate_manifest_main(argv: Optional[Sequence[str]] = None) -> int:
parser = _make_argparser('Manifest filenames.') parser = _make_argparser('Manifest filenames.')
args = parser.parse_args(argv) args = parser.parse_args(argv)
with logging_handler(args.color):
ret = 0 ret = 0
for filename in args.filenames: for filename in args.filenames:
try: try:
@ -290,7 +295,11 @@ class InvalidConfigError(FatalError):
def ordered_load_normalize_legacy_config(contents: str) -> Dict[str, Any]: def ordered_load_normalize_legacy_config(contents: str) -> Dict[str, Any]:
data = yaml_load(contents) data = yaml_load(contents)
if isinstance(data, list): if isinstance(data, list):
# TODO: Once happy, issue a deprecation warning and instructions logger.warning(
'normalizing pre-commit configuration to a top-level map. '
'support for top level list will be removed in a future version. '
'run: `pre-commit migrate-config` to automatically fix this.',
)
return {'repos': data} return {'repos': data}
else: else:
return data return data
@ -307,6 +316,8 @@ load_config = functools.partial(
def validate_config_main(argv: Optional[Sequence[str]] = None) -> int: def validate_config_main(argv: Optional[Sequence[str]] = None) -> int:
parser = _make_argparser('Config filenames.') parser = _make_argparser('Config filenames.')
args = parser.parse_args(argv) args = parser.parse_args(argv)
with logging_handler(args.color):
ret = 0 ret = 0
for filename in args.filenames: for filename in args.filenames:
try: try:

View file

@ -1,3 +1,4 @@
import argparse
import os import os
import sys import sys
@ -95,3 +96,12 @@ def use_color(setting: str) -> bool:
os.getenv('TERM') != 'dumb' os.getenv('TERM') != 'dumb'
) )
) )
def add_color_option(parser: argparse.ArgumentParser) -> None:
parser.add_argument(
'--color', default=os.environ.get('PRE_COMMIT_COLOR', 'auto'),
type=use_color,
metavar='{' + ','.join(COLOR_CHOICES) + '}',
help='Whether to use color in output. Defaults to `%(default)s`.',
)

View file

@ -8,8 +8,8 @@ from typing import Sequence
from typing import Union from typing import Union
import pre_commit.constants as C import pre_commit.constants as C
from pre_commit import color
from pre_commit import git from pre_commit import git
from pre_commit.color import add_color_option
from pre_commit.commands.autoupdate import autoupdate from pre_commit.commands.autoupdate import autoupdate
from pre_commit.commands.clean import clean from pre_commit.commands.clean import clean
from pre_commit.commands.gc import gc from pre_commit.commands.gc import gc
@ -41,15 +41,6 @@ os.environ.pop('__PYVENV_LAUNCHER__', None)
COMMANDS_NO_GIT = {'clean', 'gc', 'init-templatedir', 'sample-config'} COMMANDS_NO_GIT = {'clean', 'gc', 'init-templatedir', 'sample-config'}
def _add_color_option(parser: argparse.ArgumentParser) -> None:
parser.add_argument(
'--color', default=os.environ.get('PRE_COMMIT_COLOR', 'auto'),
type=color.use_color,
metavar='{' + ','.join(color.COLOR_CHOICES) + '}',
help='Whether to use color in output. Defaults to `%(default)s`.',
)
def _add_config_option(parser: argparse.ArgumentParser) -> None: def _add_config_option(parser: argparse.ArgumentParser) -> None:
parser.add_argument( parser.add_argument(
'-c', '--config', default=C.CONFIG_FILE, '-c', '--config', default=C.CONFIG_FILE,
@ -195,7 +186,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
'autoupdate', 'autoupdate',
help="Auto-update pre-commit config to the latest repos' versions.", help="Auto-update pre-commit config to the latest repos' versions.",
) )
_add_color_option(autoupdate_parser) add_color_option(autoupdate_parser)
_add_config_option(autoupdate_parser) _add_config_option(autoupdate_parser)
autoupdate_parser.add_argument( autoupdate_parser.add_argument(
'--bleeding-edge', action='store_true', '--bleeding-edge', action='store_true',
@ -216,11 +207,11 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
clean_parser = subparsers.add_parser( clean_parser = subparsers.add_parser(
'clean', help='Clean out pre-commit files.', 'clean', help='Clean out pre-commit files.',
) )
_add_color_option(clean_parser) add_color_option(clean_parser)
_add_config_option(clean_parser) _add_config_option(clean_parser)
hook_impl_parser = subparsers.add_parser('hook-impl') hook_impl_parser = subparsers.add_parser('hook-impl')
_add_color_option(hook_impl_parser) add_color_option(hook_impl_parser)
_add_config_option(hook_impl_parser) _add_config_option(hook_impl_parser)
hook_impl_parser.add_argument('--hook-type') hook_impl_parser.add_argument('--hook-type')
hook_impl_parser.add_argument('--hook-dir') hook_impl_parser.add_argument('--hook-dir')
@ -230,7 +221,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
hook_impl_parser.add_argument(dest='rest', nargs=argparse.REMAINDER) hook_impl_parser.add_argument(dest='rest', nargs=argparse.REMAINDER)
gc_parser = subparsers.add_parser('gc', help='Clean unused cached repos.') gc_parser = subparsers.add_parser('gc', help='Clean unused cached repos.')
_add_color_option(gc_parser) add_color_option(gc_parser)
_add_config_option(gc_parser) _add_config_option(gc_parser)
init_templatedir_parser = subparsers.add_parser( init_templatedir_parser = subparsers.add_parser(
@ -240,7 +231,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
'`git config init.templateDir`.' '`git config init.templateDir`.'
), ),
) )
_add_color_option(init_templatedir_parser) add_color_option(init_templatedir_parser)
_add_config_option(init_templatedir_parser) _add_config_option(init_templatedir_parser)
init_templatedir_parser.add_argument( init_templatedir_parser.add_argument(
'directory', help='The directory in which to write the hook script.', 'directory', help='The directory in which to write the hook script.',
@ -256,7 +247,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
install_parser = subparsers.add_parser( install_parser = subparsers.add_parser(
'install', help='Install the pre-commit script.', 'install', help='Install the pre-commit script.',
) )
_add_color_option(install_parser) add_color_option(install_parser)
_add_config_option(install_parser) _add_config_option(install_parser)
install_parser.add_argument( install_parser.add_argument(
'-f', '--overwrite', action='store_true', '-f', '--overwrite', action='store_true',
@ -286,32 +277,32 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
'useful.' 'useful.'
), ),
) )
_add_color_option(install_hooks_parser) add_color_option(install_hooks_parser)
_add_config_option(install_hooks_parser) _add_config_option(install_hooks_parser)
migrate_config_parser = subparsers.add_parser( migrate_config_parser = subparsers.add_parser(
'migrate-config', 'migrate-config',
help='Migrate list configuration to new map configuration.', help='Migrate list configuration to new map configuration.',
) )
_add_color_option(migrate_config_parser) add_color_option(migrate_config_parser)
_add_config_option(migrate_config_parser) _add_config_option(migrate_config_parser)
run_parser = subparsers.add_parser('run', help='Run hooks.') run_parser = subparsers.add_parser('run', help='Run hooks.')
_add_color_option(run_parser) add_color_option(run_parser)
_add_config_option(run_parser) _add_config_option(run_parser)
_add_run_options(run_parser) _add_run_options(run_parser)
sample_config_parser = subparsers.add_parser( sample_config_parser = subparsers.add_parser(
'sample-config', help=f'Produce a sample {C.CONFIG_FILE} file', 'sample-config', help=f'Produce a sample {C.CONFIG_FILE} file',
) )
_add_color_option(sample_config_parser) add_color_option(sample_config_parser)
_add_config_option(sample_config_parser) _add_config_option(sample_config_parser)
try_repo_parser = subparsers.add_parser( try_repo_parser = subparsers.add_parser(
'try-repo', 'try-repo',
help='Try the hooks in a repository, useful for developing new hooks.', help='Try the hooks in a repository, useful for developing new hooks.',
) )
_add_color_option(try_repo_parser) add_color_option(try_repo_parser)
_add_config_option(try_repo_parser) _add_config_option(try_repo_parser)
try_repo_parser.add_argument( try_repo_parser.add_argument(
'repo', help='Repository to source hooks from.', 'repo', help='Repository to source hooks from.',
@ -328,7 +319,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
uninstall_parser = subparsers.add_parser( uninstall_parser = subparsers.add_parser(
'uninstall', help='Uninstall the pre-commit script.', 'uninstall', help='Uninstall the pre-commit script.',
) )
_add_color_option(uninstall_parser) add_color_option(uninstall_parser)
_add_config_option(uninstall_parser) _add_config_option(uninstall_parser)
_add_hook_type_option(uninstall_parser) _add_hook_type_option(uninstall_parser)

View file

@ -30,6 +30,10 @@ def test_check_type_tag_failures(value):
check_type_tag(value) check_type_tag(value)
def test_check_type_tag_success():
check_type_tag('file')
@pytest.mark.parametrize( @pytest.mark.parametrize(
('config_obj', 'expected'), ( ('config_obj', 'expected'), (
( (
@ -110,15 +114,18 @@ def test_validate_config_main_ok():
assert not validate_config_main(('.pre-commit-config.yaml',)) assert not validate_config_main(('.pre-commit-config.yaml',))
def test_validate_config_old_list_format_ok(tmpdir): def test_validate_config_old_list_format_ok(tmpdir, cap_out):
f = tmpdir.join('cfg.yaml') f = tmpdir.join('cfg.yaml')
f.write('- {repo: meta, hooks: [{id: identity}]}') f.write('- {repo: meta, hooks: [{id: identity}]}')
assert not validate_config_main((f.strpath,)) assert not validate_config_main((f.strpath,))
start = '[WARNING] normalizing pre-commit configuration to a top-level map'
assert cap_out.get().startswith(start)
def test_validate_warn_on_unknown_keys_at_repo_level(tmpdir, caplog): def test_validate_warn_on_unknown_keys_at_repo_level(tmpdir, caplog):
f = tmpdir.join('cfg.yaml') f = tmpdir.join('cfg.yaml')
f.write( f.write(
'repos:\n'
'- repo: https://gitlab.com/pycqa/flake8\n' '- repo: https://gitlab.com/pycqa/flake8\n'
' rev: 3.7.7\n' ' rev: 3.7.7\n'
' hooks:\n' ' hooks:\n'