Created
April 18, 2017 15:39
-
-
Save cro/ae956f1d4c7fe618812687d9dc1da7dc to your computer and use it in GitHub Desktop.
Git pre-commit script for git-pillar that validates content against a voluptuous schema.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# coding: utf-8 | |
''' | |
Validate input file(s) against a Voluptuous schema | |
Pass a dash to read from stdin. | |
''' | |
from __future__ import print_function | |
import imp | |
import logging | |
import optparse | |
import sys | |
import yaml | |
try: | |
from salt.utils import voluptuous as V | |
except ImportError: | |
import voluptuous as V | |
try: | |
from logging import NullHandler | |
except ImportError: | |
class NullHandler(logging.Handler): | |
def emit(self, record): pass | |
logging.basicConfig(format='%(levelname)s %(asctime)s %(module)s: %(message)s') | |
log = logging.getLogger(__name__) | |
log.addHandler(NullHandler()) | |
VERSION = '0.1.0' | |
def check(schema, infile): | |
data = yaml.safe_load(infile) | |
return schema(data) | |
def get_file_contents(args): | |
try: | |
idx = args.index('-') | |
except ValueError: | |
use_stdin = False | |
else: | |
use_stdin = True | |
args.pop(idx) | |
if not sys.stdin.isatty() or use_stdin: | |
stdin = sys.stdin.read() | |
if stdin: | |
yield stdin | |
for filename in args: | |
with open(filename, 'r') as f: | |
yield f.read() | |
def process(schema_file, file_args): | |
module = imp.load_source('module', schema_file) | |
schema = module.schema | |
for contents in get_file_contents(file_args): | |
check(schema, contents) | |
def main(): | |
usage = 'Usage: %prog -s the_schema.py file1 file2' | |
parser = optparse.OptionParser( | |
usage=usage, | |
description=__doc__, | |
version=VERSION) | |
parser.add_option('-s', '--schema', dest='schema', | |
help='A schema to validate input file(s) against.') | |
parser.add_option('-v', dest='verbose', default=0, action='count', | |
help='Increment output verbosity; use multiple counts.') | |
opts, args = parser.parse_args() | |
log.addHandler(logging.StreamHandler()) | |
log.setLevel(max(logging.ERROR - (opts.verbose * 10), 1)) | |
if not opts.schema: | |
parser.error('Schema argument is required.') | |
if not args: | |
parser.error('No input files given.') | |
has_errors = True | |
try: | |
process(opts.schema, args) | |
except V.MultipleInvalid as exc: | |
for err in exc.errors: | |
print(err, file=sys.stderr) | |
except IOError as exc: | |
print(exc, file=sys.stderr) | |
except Exception: | |
log.debug('Unhandled exception', exc_info=True) | |
print('Unhandled exception. Run with -vvv flag.', file=sys.stderr) | |
else: | |
has_errors = False | |
return has_errors | |
if __name__ == '__main__': | |
raise SystemExit(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment