Created
October 25, 2016 16:14
-
-
Save whiteinge/bc13899e3d636e53ae9d514e4cb86b6b to your computer and use it in GitHub Desktop.
CLI tool to validate a Voluptuous schema (can be used as a pre-commit hook)
This file contains hidden or 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