Skip to content

Commit cb8dd33

Browse files
committed
Replace jsonschema with better error messages
1 parent 71bbdb5 commit cb8dd33

30 files changed

+1064
-842
lines changed

.coveragerc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
[run]
22
branch = True
3-
source =
4-
.
3+
source = .
54
omit =
65
.tox/*
76
/usr/*
@@ -11,6 +10,7 @@ omit =
1110
*/__main__.py
1211

1312
[report]
13+
show_missing = True
1414
exclude_lines =
1515
# Have to re-enable the standard pragma
1616
\#\s*pragma: no cover

pre_commit/clientlib.py

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
from __future__ import absolute_import
2+
from __future__ import unicode_literals
3+
4+
import argparse
5+
import functools
6+
7+
from aspy.yaml import ordered_load
8+
9+
import pre_commit.constants as C
10+
from pre_commit import schema
11+
from pre_commit.errors import FatalError
12+
from pre_commit.languages.all import all_languages
13+
14+
15+
def check_language(v):
16+
if v not in all_languages:
17+
raise schema.ValidationError(
18+
'Expected {} to be in {!r}'.format(v, all_languages),
19+
)
20+
21+
22+
def _make_argparser(filenames_help):
23+
parser = argparse.ArgumentParser()
24+
parser.add_argument('filenames', nargs='*', help=filenames_help)
25+
parser.add_argument('-V', '--version', action='version', version=C.VERSION)
26+
return parser
27+
28+
29+
MANIFEST_HOOK_DICT = schema.Map(
30+
'Hook', 'id',
31+
32+
schema.Required('id', schema.check_string),
33+
schema.Required('name', schema.check_string),
34+
schema.Required('entry', schema.check_string),
35+
schema.Required(
36+
'language', schema.check_and(schema.check_string, check_language),
37+
),
38+
39+
schema.Conditional(
40+
'files', schema.check_and(schema.check_string, schema.check_regex),
41+
condition_key='always_run', condition_value=False, ensure_absent=True,
42+
),
43+
44+
schema.Optional(
45+
'additional_dependencies', schema.check_array(schema.check_string), [],
46+
),
47+
schema.Optional('args', schema.check_array(schema.check_string), []),
48+
schema.Optional('always_run', schema.check_bool, False),
49+
schema.Optional('description', schema.check_string, ''),
50+
schema.Optional(
51+
'exclude',
52+
schema.check_and(schema.check_string, schema.check_regex),
53+
'^$',
54+
),
55+
schema.Optional('language_version', schema.check_string, 'default'),
56+
schema.Optional('minimum_pre_commit_version', schema.check_string, '0'),
57+
schema.Optional('stages', schema.check_array(schema.check_string), []),
58+
)
59+
MANIFEST_SCHEMA = schema.Array(MANIFEST_HOOK_DICT)
60+
61+
62+
class InvalidManifestError(FatalError):
63+
pass
64+
65+
66+
load_manifest = functools.partial(
67+
schema.load_from_filename,
68+
schema=MANIFEST_SCHEMA,
69+
load_strategy=ordered_load,
70+
exc_tp=InvalidManifestError,
71+
)
72+
73+
74+
def validate_manifest_main(argv=None):
75+
parser = _make_argparser('Manifest filenames.')
76+
args = parser.parse_args(argv)
77+
ret = 0
78+
for filename in args.filenames:
79+
try:
80+
load_manifest(filename)
81+
except InvalidManifestError as e:
82+
print(e)
83+
ret = 1
84+
return ret
85+
86+
87+
_LOCAL_SENTINEL = 'local'
88+
CONFIG_HOOK_DICT = schema.Map(
89+
'Hook', 'id',
90+
91+
schema.Required('id', schema.check_string),
92+
93+
# All keys in manifest hook dict are valid in a config hook dict, but
94+
# are optional.
95+
# No defaults are provided here as the config is merged on top of the
96+
# manifest.
97+
*[
98+
schema.OptionalNoDefault(item.key, item.check_fn)
99+
for item in MANIFEST_HOOK_DICT.items
100+
if item.key != 'id'
101+
]
102+
)
103+
CONFIG_REPO_DICT = schema.Map(
104+
'Repository', 'repo',
105+
106+
schema.Required('repo', schema.check_string),
107+
schema.RequiredRecurse('hooks', schema.Array(CONFIG_HOOK_DICT)),
108+
109+
schema.Conditional(
110+
'sha', schema.check_string,
111+
condition_key='repo', condition_value=schema.Not(_LOCAL_SENTINEL),
112+
ensure_absent=True,
113+
),
114+
)
115+
CONFIG_SCHEMA = schema.Array(CONFIG_REPO_DICT)
116+
117+
118+
def is_local_repo(repo_entry):
119+
return repo_entry['repo'] == _LOCAL_SENTINEL
120+
121+
122+
class InvalidConfigError(FatalError):
123+
pass
124+
125+
126+
load_config = functools.partial(
127+
schema.load_from_filename,
128+
schema=CONFIG_SCHEMA,
129+
load_strategy=ordered_load,
130+
exc_tp=InvalidConfigError,
131+
)
132+
133+
134+
def validate_config_main(argv=None):
135+
parser = _make_argparser('Config filenames.')
136+
args = parser.parse_args(argv)
137+
ret = 0
138+
for filename in args.filenames:
139+
try:
140+
load_config(filename)
141+
except InvalidConfigError as e:
142+
print(e)
143+
ret = 1
144+
return ret

pre_commit/clientlib/__init__.py

Whitespace-only changes.

pre_commit/clientlib/validate_base.py

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

pre_commit/clientlib/validate_config.py

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

0 commit comments

Comments
 (0)