Skip to content

Commit 1e4de98

Browse files
paulhfischerasottile
authored andcommitted
added warning if mutable rev is used
1 parent 8670d0b commit 1e4de98

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

pre_commit/clientlib.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import argparse
22
import functools
33
import logging
4+
import re
45
import shlex
56
import sys
67
from typing import Any
@@ -112,6 +113,25 @@ def validate_manifest_main(argv: Optional[Sequence[str]] = None) -> int:
112113
META = 'meta'
113114

114115

116+
# should inherit from cfgv.Conditional if sha support is dropped
117+
class WarnMutableRev(cfgv.ConditionalOptional):
118+
def check(self, dct: Dict[str, Any]) -> None:
119+
super().check(dct)
120+
121+
if self.key in dct:
122+
rev = dct[self.key]
123+
124+
if '.' not in rev and not re.match(r'^[a-fA-F0-9]+$', rev):
125+
logger.warning(
126+
f'The {self.key!r} field of repo {dct["repo"]!r} '
127+
f'appears to be a mutable reference '
128+
f'(moving tag / branch). Mutable references are never '
129+
f'updated after first install and are not supported. '
130+
f'See https://pre-commit.com/#using-the-latest-version-for-a-repository ' # noqa: E501
131+
f'for more details.',
132+
)
133+
134+
115135
class OptionalSensibleRegex(cfgv.OptionalNoDefault):
116136
def check(self, dct: Dict[str, Any]) -> None:
117137
super().check(dct)
@@ -261,6 +281,14 @@ def warn_unknown_keys_repo(
261281
),
262282

263283
MigrateShaToRev(),
284+
WarnMutableRev(
285+
'rev',
286+
cfgv.check_string,
287+
'',
288+
'repo',
289+
cfgv.NotIn(LOCAL, META),
290+
True,
291+
),
264292
cfgv.WarnAdditionalKeys(('repo', 'rev', 'hooks'), warn_unknown_keys_repo),
265293
)
266294
DEFAULT_LANGUAGE_VERSION = cfgv.Map(

tests/clientlib_test.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,70 @@ def test_ci_key_must_be_map():
180180
cfgv.validate({'ci': 'invalid', 'repos': []}, CONFIG_SCHEMA)
181181

182182

183+
@pytest.mark.parametrize(
184+
'rev',
185+
(
186+
'v0.12.4',
187+
'b27f281',
188+
'b27f281eb9398fc8504415d7fbdabf119ea8c5e1',
189+
'19.10b0',
190+
'4.3.21-2',
191+
),
192+
)
193+
def test_warn_mutable_rev_ok(caplog, rev):
194+
config_obj = {
195+
'repo': 'https://gitlab.com/pycqa/flake8',
196+
'rev': rev,
197+
'hooks': [{'id': 'flake8'}],
198+
}
199+
cfgv.validate(config_obj, CONFIG_REPO_DICT)
200+
201+
assert caplog.record_tuples == []
202+
203+
204+
@pytest.mark.parametrize(
205+
'rev',
206+
(
207+
'',
208+
'HEAD',
209+
'stable',
210+
'master',
211+
'some_branch_name',
212+
),
213+
)
214+
def test_warn_mutable_rev_invalid(caplog, rev):
215+
config_obj = {
216+
'repo': 'https://gitlab.com/pycqa/flake8',
217+
'rev': rev,
218+
'hooks': [{'id': 'flake8'}],
219+
}
220+
cfgv.validate(config_obj, CONFIG_REPO_DICT)
221+
222+
assert caplog.record_tuples == [
223+
(
224+
'pre_commit',
225+
logging.WARNING,
226+
"The 'rev' field of repo 'https://gitlab.com/pycqa/flake8' "
227+
'appears to be a mutable reference (moving tag / branch). '
228+
'Mutable references are never updated after first install and are '
229+
'not supported. '
230+
'See https://pre-commit.com/#using-the-latest-version-for-a-repository ' # noqa: E501
231+
'for more details.',
232+
),
233+
]
234+
235+
236+
def test_warn_mutable_rev_conditional():
237+
config_obj = {
238+
'repo': 'meta',
239+
'rev': '3.7.7',
240+
'hooks': [{'id': 'flake8'}],
241+
}
242+
243+
with pytest.raises(cfgv.ValidationError):
244+
cfgv.validate(config_obj, CONFIG_REPO_DICT)
245+
246+
183247
def test_validate_optional_sensible_regex(caplog):
184248
config_obj = {
185249
'id': 'flake8',

0 commit comments

Comments
 (0)