Files
pre-commit/pre_commit/clientlib.py
2017-03-08 14:07:00 -08:00

145 lines
3.8 KiB
Python

from __future__ import absolute_import
from __future__ import unicode_literals
import argparse
import functools
from aspy.yaml import ordered_load
import pre_commit.constants as C
from pre_commit import schema
from pre_commit.errors import FatalError
from pre_commit.languages.all import all_languages
def check_language(v):
if v not in all_languages:
raise schema.ValidationError(
'Expected {} to be in {!r}'.format(v, all_languages),
)
def _make_argparser(filenames_help):
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*', help=filenames_help)
parser.add_argument('-V', '--version', action='version', version=C.VERSION)
return parser
MANIFEST_HOOK_DICT = schema.Map(
'Hook', 'id',
schema.Required('id', schema.check_string),
schema.Required('name', schema.check_string),
schema.Required('entry', schema.check_string),
schema.Required(
'language', schema.check_and(schema.check_string, check_language),
),
schema.Conditional(
'files', schema.check_and(schema.check_string, schema.check_regex),
condition_key='always_run', condition_value=False, ensure_absent=True,
),
schema.Optional(
'additional_dependencies', schema.check_array(schema.check_string), [],
),
schema.Optional('args', schema.check_array(schema.check_string), []),
schema.Optional('always_run', schema.check_bool, False),
schema.Optional('description', schema.check_string, ''),
schema.Optional(
'exclude',
schema.check_and(schema.check_string, schema.check_regex),
'^$',
),
schema.Optional('language_version', schema.check_string, 'default'),
schema.Optional('minimum_pre_commit_version', schema.check_string, '0'),
schema.Optional('stages', schema.check_array(schema.check_string), []),
)
MANIFEST_SCHEMA = schema.Array(MANIFEST_HOOK_DICT)
class InvalidManifestError(FatalError):
pass
load_manifest = functools.partial(
schema.load_from_filename,
schema=MANIFEST_SCHEMA,
load_strategy=ordered_load,
exc_tp=InvalidManifestError,
)
def validate_manifest_main(argv=None):
parser = _make_argparser('Manifest filenames.')
args = parser.parse_args(argv)
ret = 0
for filename in args.filenames:
try:
load_manifest(filename)
except InvalidManifestError as e:
print(e)
ret = 1
return ret
_LOCAL_SENTINEL = 'local'
CONFIG_HOOK_DICT = schema.Map(
'Hook', 'id',
schema.Required('id', schema.check_string),
# All keys in manifest hook dict are valid in a config hook dict, but
# are optional.
# No defaults are provided here as the config is merged on top of the
# manifest.
*[
schema.OptionalNoDefault(item.key, item.check_fn)
for item in MANIFEST_HOOK_DICT.items
if item.key != 'id'
]
)
CONFIG_REPO_DICT = schema.Map(
'Repository', 'repo',
schema.Required('repo', schema.check_string),
schema.RequiredRecurse('hooks', schema.Array(CONFIG_HOOK_DICT)),
schema.Conditional(
'sha', schema.check_string,
condition_key='repo', condition_value=schema.Not(_LOCAL_SENTINEL),
ensure_absent=True,
),
)
CONFIG_SCHEMA = schema.Array(CONFIG_REPO_DICT)
def is_local_repo(repo_entry):
return repo_entry['repo'] == _LOCAL_SENTINEL
class InvalidConfigError(FatalError):
pass
load_config = functools.partial(
schema.load_from_filename,
schema=CONFIG_SCHEMA,
load_strategy=ordered_load,
exc_tp=InvalidConfigError,
)
def validate_config_main(argv=None):
parser = _make_argparser('Config filenames.')
args = parser.parse_args(argv)
ret = 0
for filename in args.filenames:
try:
load_config(filename)
except InvalidConfigError as e:
print(e)
ret = 1
return ret