Skip to content

Commit bc9344b

Browse files
authored
Merge branch 'master' into meta-hooks
2 parents 8a0dd01 + 9e193f7 commit bc9344b

File tree

6 files changed

+73
-127
lines changed

6 files changed

+73
-127
lines changed

pre_commit/commands/autoupdate.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def _update_repo(repo_config, runner, tags_only):
5757

5858
# See if any of our hooks were deleted with the new commits
5959
hooks = {hook['id'] for hook in repo.repo_config['hooks']}
60-
hooks_missing = hooks - (hooks & set(new_repo.manifest.hooks))
60+
hooks_missing = hooks - (hooks & set(new_repo.manifest_hooks))
6161
if hooks_missing:
6262
raise RepositoryCannotBeUpdatedError(
6363
'Cannot update because the tip of master is missing these hooks:\n'

pre_commit/commands/try_repo.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
import pre_commit.constants as C
1010
from pre_commit import git
1111
from pre_commit import output
12+
from pre_commit.clientlib import load_manifest
1213
from pre_commit.commands.run import run
13-
from pre_commit.manifest import Manifest
1414
from pre_commit.runner import Runner
1515
from pre_commit.store import Store
1616
from pre_commit.util import tmpdir
@@ -23,8 +23,10 @@ def try_repo(args):
2323
if args.hook:
2424
hooks = [{'id': args.hook}]
2525
else:
26-
manifest = Manifest(Store(tempdir).clone(args.repo, ref))
27-
hooks = [{'id': hook_id} for hook_id in sorted(manifest.hooks)]
26+
repo_path = Store(tempdir).clone(args.repo, ref)
27+
manifest = load_manifest(os.path.join(repo_path, C.MANIFEST_FILE))
28+
manifest = sorted(manifest, key=lambda hook: hook['id'])
29+
hooks = [{'id': hook['id']} for hook in manifest]
2830

2931
items = (('repo', args.repo), ('sha', ref), ('hooks', hooks))
3032
config = {'repos': [collections.OrderedDict(items)]}

pre_commit/manifest.py

Lines changed: 0 additions & 28 deletions
This file was deleted.

pre_commit/repository.py

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
from pre_commit import git
1818
from pre_commit.clientlib import is_local_repo
1919
from pre_commit.clientlib import is_meta_repo
20+
from pre_commit.clientlib import load_manifest
2021
from pre_commit.clientlib import MANIFEST_HOOK_DICT
2122
from pre_commit.languages.all import languages
2223
from pre_commit.languages.helpers import environment_dir
23-
from pre_commit.manifest import Manifest
2424
from pre_commit.prefixed_command_runner import PrefixedCommandRunner
2525
from pre_commit.schema import apply_defaults
2626
from pre_commit.schema import validate
@@ -105,20 +105,27 @@ def _need_installed():
105105
_write_state(cmd_runner, venv, state)
106106

107107

108-
def _validate_minimum_version(hook):
109-
hook_version = pkg_resources.parse_version(
110-
hook['minimum_pre_commit_version'],
111-
)
112-
if hook_version > C.VERSION_PARSED:
108+
def _hook(*hook_dicts):
109+
ret, rest = dict(hook_dicts[0]), hook_dicts[1:]
110+
for dct in rest:
111+
ret.update(dct)
112+
113+
version = pkg_resources.parse_version(ret['minimum_pre_commit_version'])
114+
if version > C.VERSION_PARSED:
113115
logger.error(
114-
'The hook `{}` requires pre-commit version {} but '
115-
'version {} is installed. '
116+
'The hook `{}` requires pre-commit version {} but version {} '
117+
'is installed. '
116118
'Perhaps run `pip install --upgrade pre-commit`.'.format(
117-
hook['id'], hook_version, C.VERSION_PARSED,
119+
ret['id'], version, C.VERSION_PARSED,
118120
),
119121
)
120122
exit(1)
121-
return hook
123+
124+
if ret['language_version'] == 'default':
125+
language = languages[ret['language']]
126+
ret['language_version'] = language.get_default_version()
127+
128+
return ret
122129

123130

124131
class Repository(object):
@@ -150,13 +157,14 @@ def _cmd_runner_from_deps(self, language_name, deps):
150157
return self._cmd_runner
151158

152159
@cached_property
153-
def manifest(self):
154-
return Manifest(self._repo_path)
160+
def manifest_hooks(self):
161+
manifest_path = os.path.join(self._repo_path, C.MANIFEST_FILE)
162+
return {hook['id']: hook for hook in load_manifest(manifest_path)}
155163

156164
@cached_property
157165
def hooks(self):
158166
for hook in self.repo_config['hooks']:
159-
if hook['id'] not in self.manifest.hooks:
167+
if hook['id'] not in self.manifest_hooks:
160168
logger.error(
161169
'`{}` is not present in repository {}. '
162170
'Typo? Perhaps it is introduced in a newer version? '
@@ -166,10 +174,8 @@ def hooks(self):
166174
)
167175
exit(1)
168176

169-
_validate_minimum_version(self.manifest.hooks[hook['id']])
170-
171177
return tuple(
172-
(hook['id'], dict(self.manifest.hooks[hook['id']], **hook))
178+
(hook['id'], _hook(self.manifest_hooks[hook['id']], hook))
173179
for hook in self.repo_config['hooks']
174180
)
175181

@@ -220,16 +226,14 @@ def manifest(self):
220226

221227
@cached_property
222228
def hooks(self):
229+
def _from_manifest_dct(dct):
230+
dct = validate(dct, MANIFEST_HOOK_DICT)
231+
dct = apply_defaults(dct, MANIFEST_HOOK_DICT)
232+
dct = _hook(dct)
233+
return dct
234+
223235
return tuple(
224-
(
225-
hook['id'],
226-
_validate_minimum_version(
227-
apply_defaults(
228-
validate(hook, MANIFEST_HOOK_DICT),
229-
MANIFEST_HOOK_DICT,
230-
),
231-
),
232-
)
236+
(hook['id'], _from_manifest_dct(hook))
233237
for hook in self.repo_config['hooks']
234238
)
235239

tests/manifest_test.py

Lines changed: 0 additions & 70 deletions
This file was deleted.

tests/repository_test.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@ def test_python_hook(tempdir_factory, store):
7171
)
7272

7373

74+
@pytest.mark.integration
75+
def test_python_hook_default_version(tempdir_factory, store):
76+
# make sure that this continues to work for platforms where default
77+
# language detection does not work
78+
with mock.patch.object(
79+
python, 'get_default_version', return_value='default',
80+
):
81+
test_python_hook(tempdir_factory, store)
82+
83+
7484
@pytest.mark.integration
7585
def test_python_hook_args_with_spaces(tempdir_factory, store):
7686
_test_hook_repo(
@@ -690,6 +700,8 @@ def test_local_python_repo(store):
690700
config = {'repo': 'local', 'hooks': hooks}
691701
repo = Repository.create(config, store)
692702
(_, hook), = repo.hooks
703+
# language_version should have been adjusted to the interpreter version
704+
assert hook['language_version'] != 'default'
693705
ret = repo.run_hook(hook, ('filename',))
694706
assert ret[0] == 0
695707
assert _norm_out(ret[1]) == b"['filename']\nHello World\n"
@@ -746,3 +758,29 @@ def test_versions_ok(tempdir_factory, store, version):
746758
config = make_config_from_repo(path)
747759
# Should succeed
748760
Repository.create(config, store).require_installed()
761+
762+
763+
def test_manifest_hooks(tempdir_factory, store):
764+
path = make_repo(tempdir_factory, 'script_hooks_repo')
765+
config = make_config_from_repo(path)
766+
repo = Repository.create(config, store)
767+
768+
assert repo.manifest_hooks['bash_hook'] == {
769+
'always_run': False,
770+
'additional_dependencies': [],
771+
'args': [],
772+
'description': '',
773+
'entry': 'bin/hook.sh',
774+
'exclude': '^$',
775+
'files': '',
776+
'id': 'bash_hook',
777+
'language': 'script',
778+
'language_version': 'default',
779+
'log_file': '',
780+
'minimum_pre_commit_version': '0',
781+
'name': 'Bash hook',
782+
'pass_filenames': True,
783+
'stages': [],
784+
'types': ['file'],
785+
'exclude_types': [],
786+
}

0 commit comments

Comments
 (0)