mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-02-17 08:14:42 +04:00
Add an option to require a specific pre-commit version
This commit is contained in:
parent
c24f78b1a5
commit
ce307a16e0
5 changed files with 68 additions and 0 deletions
|
|
@ -23,6 +23,9 @@ MANIFEST_JSON_SCHEMA = {
|
||||||
'exclude': {'type': 'string', 'default': '^$'},
|
'exclude': {'type': 'string', 'default': '^$'},
|
||||||
'language': {'type': 'string'},
|
'language': {'type': 'string'},
|
||||||
'language_version': {'type': 'string', 'default': 'default'},
|
'language_version': {'type': 'string', 'default': 'default'},
|
||||||
|
'minimum_pre_commit_version': {
|
||||||
|
'type': 'string', 'default': '0.0.0',
|
||||||
|
},
|
||||||
'files': {'type': 'string'},
|
'files': {'type': 'string'},
|
||||||
'stages': {
|
'stages': {
|
||||||
'type': 'array',
|
'type': 'array',
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import logging
|
||||||
import shutil
|
import shutil
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
|
import pkg_resources
|
||||||
from cached_property import cached_property
|
from cached_property import cached_property
|
||||||
|
|
||||||
from pre_commit import git
|
from pre_commit import git
|
||||||
|
|
@ -18,6 +19,10 @@ from pre_commit.prefixed_command_runner import PrefixedCommandRunner
|
||||||
|
|
||||||
logger = logging.getLogger('pre_commit')
|
logger = logging.getLogger('pre_commit')
|
||||||
|
|
||||||
|
_pre_commit_version = pkg_resources.parse_version(
|
||||||
|
pkg_resources.get_distribution('pre-commit').version
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Repository(object):
|
class Repository(object):
|
||||||
def __init__(self, repo_config, repo_path_getter):
|
def __init__(self, repo_config, repo_path_getter):
|
||||||
|
|
@ -71,6 +76,18 @@ class Repository(object):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
hook_version = pkg_resources.parse_version(
|
||||||
|
self.manifest.hooks[hook['id']]['minimum_pre_commit_version'],
|
||||||
|
)
|
||||||
|
if hook_version > _pre_commit_version:
|
||||||
|
logger.error(
|
||||||
|
'The hook `{0}` requires pre-commit version {1} but '
|
||||||
|
'version {2} is installed. '
|
||||||
|
'Perhaps run `pip install --upgrade pre-commit`.'.format(
|
||||||
|
hook['id'], hook_version, _pre_commit_version,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
exit(1)
|
||||||
return tuple(
|
return tuple(
|
||||||
(hook['id'], dict(self.manifest.hooks[hook['id']], **hook))
|
(hook['id'], dict(self.manifest.hooks[hook['id']], **hook))
|
||||||
for hook in self.repo_config['hooks']
|
for hook in self.repo_config['hooks']
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import contextlib
|
||||||
import io
|
import io
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
from aspy.yaml import ordered_dump
|
from aspy.yaml import ordered_dump
|
||||||
|
from aspy.yaml import ordered_load
|
||||||
|
|
||||||
import pre_commit.constants as C
|
import pre_commit.constants as C
|
||||||
from pre_commit.clientlib.validate_config import CONFIG_JSON_SCHEMA
|
from pre_commit.clientlib.validate_config import CONFIG_JSON_SCHEMA
|
||||||
|
|
@ -35,6 +37,17 @@ def make_repo(tempdir_factory, repo_source):
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def modify_manifest(path):
|
||||||
|
"""Modify the manifest yielded by this context to write to hooks.yaml."""
|
||||||
|
manifest_path = os.path.join(path, C.MANIFEST_FILE)
|
||||||
|
manifest = ordered_load(io.open(manifest_path).read())
|
||||||
|
yield manifest
|
||||||
|
with io.open(manifest_path, 'w') as manifest_file:
|
||||||
|
manifest_file.write(ordered_dump(manifest, **C.YAML_DUMP_KWARGS))
|
||||||
|
cmd_output('git', 'commit', '-am', 'update hooks.yaml', cwd=path)
|
||||||
|
|
||||||
|
|
||||||
def config_with_local_hooks():
|
def config_with_local_hooks():
|
||||||
return OrderedDict((
|
return OrderedDict((
|
||||||
('repo', 'local'),
|
('repo', 'local'),
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ def test_manifest_contents(manifest):
|
||||||
'id': 'bash_hook',
|
'id': 'bash_hook',
|
||||||
'language': 'script',
|
'language': 'script',
|
||||||
'language_version': 'default',
|
'language_version': 'default',
|
||||||
|
'minimum_pre_commit_version': '0.0.0',
|
||||||
'name': 'Bash hook',
|
'name': 'Bash hook',
|
||||||
'stages': [],
|
'stages': [],
|
||||||
}]
|
}]
|
||||||
|
|
@ -42,6 +43,7 @@ def test_hooks(manifest):
|
||||||
'id': 'bash_hook',
|
'id': 'bash_hook',
|
||||||
'language': 'script',
|
'language': 'script',
|
||||||
'language_version': 'default',
|
'language_version': 'default',
|
||||||
|
'minimum_pre_commit_version': '0.0.0',
|
||||||
'name': 'Bash hook',
|
'name': 'Bash hook',
|
||||||
'stages': [],
|
'stages': [],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,11 @@ import io
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
import pkg_resources
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from pre_commit import five
|
from pre_commit import five
|
||||||
|
|
@ -24,6 +26,7 @@ from testing.fixtures import config_with_local_hooks
|
||||||
from testing.fixtures import git_dir
|
from testing.fixtures import git_dir
|
||||||
from testing.fixtures import make_config_from_repo
|
from testing.fixtures import make_config_from_repo
|
||||||
from testing.fixtures import make_repo
|
from testing.fixtures import make_repo
|
||||||
|
from testing.fixtures import modify_manifest
|
||||||
from testing.util import skipif_slowtests_false
|
from testing.util import skipif_slowtests_false
|
||||||
from testing.util import xfailif_no_pcre_support
|
from testing.util import xfailif_no_pcre_support
|
||||||
from testing.util import xfailif_windows_no_node
|
from testing.util import xfailif_windows_no_node
|
||||||
|
|
@ -525,3 +528,33 @@ def test_hook_id_not_present(tempdir_factory, store, fake_log_handler):
|
||||||
'Typo? Perhaps it is introduced in a newer version? '
|
'Typo? Perhaps it is introduced in a newer version? '
|
||||||
'Often `pre-commit autoupdate` fixes this.'.format(path)
|
'Often `pre-commit autoupdate` fixes this.'.format(path)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_too_new_version(tempdir_factory, store, fake_log_handler):
|
||||||
|
path = make_repo(tempdir_factory, 'script_hooks_repo')
|
||||||
|
with modify_manifest(path) as manifest:
|
||||||
|
manifest[0]['minimum_pre_commit_version'] = '999.0.0'
|
||||||
|
config = make_config_from_repo(path)
|
||||||
|
repo = Repository.create(config, store)
|
||||||
|
with pytest.raises(SystemExit):
|
||||||
|
repo.install()
|
||||||
|
msg = fake_log_handler.handle.call_args[0][0].msg
|
||||||
|
assert re.match(
|
||||||
|
r'^The hook `bash_hook` requires pre-commit version 999\.0\.0 but '
|
||||||
|
r'version \d+\.\d+\.\d+ is installed. '
|
||||||
|
r'Perhaps run `pip install --upgrade pre-commit`\.$',
|
||||||
|
msg,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'version',
|
||||||
|
('0.1.0', pkg_resources.get_distribution('pre-commit').version),
|
||||||
|
)
|
||||||
|
def test_versions_ok(tempdir_factory, store, version):
|
||||||
|
path = make_repo(tempdir_factory, 'script_hooks_repo')
|
||||||
|
with modify_manifest(path) as manifest:
|
||||||
|
manifest[0]['minimum_pre_commit_version'] = version
|
||||||
|
config = make_config_from_repo(path)
|
||||||
|
# Should succeed
|
||||||
|
Repository.create(config, store).install()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue