#!/usr/bin/python import sys import os import subprocess import traceback import yaml run_pep8 = False try: import pep8 run_pep8 = True except: print "PEP8 is not available" def print_stderr(message): sys.stderr.write(message) sys.stderr.write("\n") def publish_result(result_message_list): result_message = '\n'.join(result_message_list) f = open('build-error.txt', 'a') f.write("\n\n") f.write(result_message) f.write("\n\n") f.close() print_stderr(result_message) def pep8_check(filepath, ignore_options=None): _fmt = "%(row)d:%(col)d: %(code)s %(text)s" options = { 'ignore': ignore_options, "show_source": True} pep8_checker = pep8.StyleGuide(options) fchecker = pep8_checker.checker_class( filepath, options=pep8_checker.options) fchecker.check_all() if fchecker.report.file_errors > 0: result_message_list = [] result_message_list.append("* PEP8: [WARNING]: " + filepath) fchecker.report.print_statistics() for line_number, offset, code, text, doc in fchecker.report._deferred_print: result_message_list.append( _fmt % { 'path': filepath, 'row': fchecker.report.line_offset + line_number, 'col': offset + 1, 'code': code, 'text': text, }) publish_result(result_message_list) def metadata_check(filepath): if filepath.lower().endswith("yaml"): with open(filepath, "r") as f: result_message_list = [] y = yaml.load(f.read()) if not 'metadata' in y.keys(): result_message_list.append("* METADATA [FAILED]: " + filepath) result_message_list.append("\tmetadata section missing") publish_result(result_message_list) exit(1) metadata_dict = y['metadata'] mandatory_keys = set([ 'name', 'format', 'description', 'maintainer', 'os', 'devices']) if not mandatory_keys.issubset(set(metadata_dict.keys())): result_message_list.append("* METADATA [FAILED]: " + filepath) result_message_list.append("\tmandatory keys missing: %s" % \ mandatory_keys.difference(set(metadata_dict.keys()))) result_message_list.append("\tactual keys present: %s" % \ metadata_dict.keys()) publish_result(result_message_list) exit(1) for key in mandatory_keys: if len(metadata_dict[key]) == 0: result_message_list.append("* METADATA [FAILED]: " + filepath) result_message_list.append("\t%s has no content" % key) publish_result(result_message_list) exit(1) result_message_list.append("* METADATA [PASSED]: " + filepath) publish_result(result_message_list) def validate_yaml(filename): with open(filename, "r") as f: try: y = yaml.load(f.read()) message = "* YAMLVALID: [PASSED]: " + filename print_stderr(message) except: message = "* YAMLVALID: [FAILED]: " + filename result_message_list = [] result_message_list.append(message) result_message_list.append("\n\n") exc_type, exc_value, exc_traceback = sys.exc_info() for line in traceback.format_exception_only(exc_type, exc_value): result_message_list.append(' ' + line) publish_result(result_message_list) exit(1) def validate_shell(filename): cmd = './checkbashisms %s 2>&1' % filename try: output = subprocess.check_output(cmd, shell=True) message = '* CHECKBASHISMS: [PASSED]: %s' % filename print_stderr(message) except subprocess.CalledProcessError as e: result_message_list = [] result_message_list.append('* CHECKBASHISMS: [FAILED]: %s' % filename) result_message_list.append('* CHECKBASHISMS: [OUTPUT]:') for line in e.output.splitlines(): result_message_list.append(' ' + line) publish_result(result_message_list) exit(1) def run_unit_tests(ignore_options): for root, dirs, files in os.walk('.'): if not root.startswith("./.git"): for name in files: if name.endswith("yaml"): validate_yaml(root + "/" + name) metadata_check(root + "/" + name) if run_pep8 and name.endswith("py"): pep8_check(root + "/" + name, ignore_options) # disable checkbashisms for now #if name.endswith("sh"): # validate_shell(root + "/" + name) def main(ignore_options=None): run_unit_tests(ignore_options) exit(0) if __name__ == '__main__': if len(sys.argv) > 1: main(sys.argv[1]) else: main()