#!/usr/bin/env python # -*- coding: utf-8 -*- # import os import json import fstools import re import subprocess class termcolors: HEADER = '\033[95m' OKBLUE = '\033[94m' OKGREEN = '\033[92m' WARNING = '\033[93m' FAIL = '\033[91m' ENDC = '\033[0m' BOLD = '\033[1m' UNDERLINE = '\033[4m' STATUS_RELEASED = 'RELEASED' STATUS_AVAILABLE = 'AVAILABLE' STATUS_IN_WORK = 'IN_WORK' STATUS_EXISTS = 'EXISTS' STATUS_OLD = 'OLD' STATUS_MISSING = 'MISSING' # STATUS_CLEAN = 'CLEAN' STATUS_CHANGED = 'CHANGED' # STATUS_UNKNOWN = 'UNKNOWN' STATUS_LENGTH = 13 STR_STATUS = { STATUS_RELEASED: termcolors.OKGREEN + (STATUS_LENGTH - len(STATUS_RELEASED)) * ' ' + STATUS_RELEASED + termcolors.ENDC, STATUS_AVAILABLE: termcolors.OKGREEN + (STATUS_LENGTH - len(STATUS_AVAILABLE)) * ' ' + STATUS_AVAILABLE + termcolors.ENDC, STATUS_IN_WORK: termcolors.WARNING + (STATUS_LENGTH - len(STATUS_IN_WORK)) * ' ' + STATUS_IN_WORK + termcolors.ENDC, STATUS_OLD: termcolors.WARNING + (STATUS_LENGTH - len(STATUS_OLD)) * ' ' + STATUS_OLD + termcolors.ENDC, STATUS_EXISTS: termcolors.WARNING + (STATUS_LENGTH - len(STATUS_EXISTS)) * ' ' + STATUS_EXISTS + termcolors.ENDC, STATUS_MISSING: termcolors.FAIL + (STATUS_LENGTH - len(STATUS_MISSING)) * ' ' + STATUS_MISSING + termcolors.ENDC, # STATUS_CLEAN: termcolors.OKGREEN + (STATUS_LENGTH - len(STATUS_CLEAN)) * ' ' + STATUS_CLEAN + termcolors.ENDC, STATUS_CHANGED: termcolors.WARNING + (STATUS_LENGTH - len(STATUS_CHANGED)) * ' ' + STATUS_CHANGED + termcolors.ENDC, # STATUS_UNKNOWN: termcolors.FAIL + (STATUS_LENGTH - len(STATUS_UNKNOWN)) * ' ' + STATUS_UNKNOWN + termcolors.ENDC, } def module_status_head(): rv = termcolors.BOLD + termcolors.UNDERLINE + 'Status of the unittests for pylibs:\n' + termcolors.ENDC LINE_FORMAT = '%25s%' + str(STATUS_LENGTH) + 's%' + str(STATUS_LENGTH) + 's%' + str(STATUS_LENGTH) + 's%' + str(STATUS_LENGTH) + 's%' + str(STATUS_LENGTH) + 's%' + str(STATUS_LENGTH) + 's\n' rv += termcolors.BOLD + termcolors.HEADER + LINE_FORMAT % ( 'Library', 'UT-Status', 'DOC-Status', 'Versions', 'UT-Coverage', 'SPEC-Status', 'GIT-Status', ) rv += (25 + 6 * STATUS_LENGTH) * '-' + '\n' + termcolors.ENDC return rv def module_status_line(module_folder): rv = '%25s%s%s%s%s%s%s\n' % ( os.path.basename(module_folder) + ':', STR_STATUS.get(module_unittest_status(module_folder), STATUS_UNKNOWN), STR_STATUS.get(module_doc_status(module_folder), STATUS_UNKNOWN), module_unittest_versions(module_folder), module_unittest_coverage(module_folder), STR_STATUS.get(module_spec_status(module_folder), STATUS_UNKNOWN), STR_STATUS.get(module_git_status(module_folder), STATUS_UNKNOWN), ) return rv def module_unittest_status(module_folder): try: with open(os.path.join(module_folder, 'pylibs', os.path.basename(module_folder), '_testresults_', 'unittest.json'), 'r') as fh: ut_lib = json.loads(fh.read()) except IOError: return STATUS_MISSING else: try: with open(os.path.join(module_folder, 'unittest', 'testresults', 'unittest.json'), 'r') as fh: ut_ut = json.loads(fh.read()) except IOError: return STATUS_UNKNOWN else: if ut_ut['testobject_information'] != ut_lib['testobject_information'] or ut_ut['unittest_information'] != ut_lib['unittest_information']: return STATUS_OLD else: ut_status = ut_lib.get('testobject_information', {}).get('State', 'unknown') if 'released' in ut_status.lower(): return STATUS_RELEASED elif 'work' in ut_status.lower(): return STATUS_IN_WORK else: return STATUS_UNKNOWN def module_unittest_versions(module_folder): try: with open(os.path.join(module_folder, 'unittest', 'testresults', 'unittest.json'), 'r') as fh: ut = json.loads(fh.read()) except IOError: return STR_STATUS[STATUS_UNKNOWN] else: interpreters = ut.get('testobject_information', '').get('Supported Interpreters') interpreters = interpreters.split(',') for i in range(len(interpreters)): interpreters[i] = interpreters[i].strip() interpreters[i] = interpreters[i][6:] rv = ', '.join(interpreters) return (STATUS_LENGTH - len(rv)) * ' ' + rv def module_unittest_coverage(module_folder): try: with open(os.path.join(module_folder, 'unittest', 'testresults', 'unittest.json'), 'r') as fh: ut = json.loads(fh.read()) except IOError: return STR_STATUS[STATUS_UNKNOWN] else: lcov = ut.get('coverage_information', [{}])[0].get('line_coverage') bcov = ut.get('coverage_information', [{}])[0].get('branch_coverage') if lcov is None or bcov is None: return STR_STATUS[STATUS_UNKNOWN] elif lcov > 90: rv = termcolors.OKGREEN + '%3d%% (%3d%%)' % (lcov, bcov) + termcolors.ENDC else: rv = termcolors.WARNING + '%3d%% (%3d%%)' % (lcov, bcov) + termcolors.ENDC return (STATUS_LENGTH - 11) * ' ' + rv def module_git_status(module_folder): p = subprocess.Popen("git -C %s status" % module_folder, stdout=subprocess.PIPE, shell=True) output = p.communicate()[0] p_status = p.wait() if p_status == 0: if b"nichts zu committen" in output and b"um lokale Commits zu publizieren" not in output: return STATUS_CLEAN else: return STATUS_CHANGED else: return STATUS_UNKNOWN def module_doc_status(module_folder): if os.path.exists(os.path.join(module_folder, 'pylibs', os.path.basename(module_folder), '_docs_', 'index.html')): return STATUS_AVAILABLE else: if os.path.exists(os.path.join(module_folder, 'docs', 'index.rst')): return STATUS_IN_WORK else: return STATUS_MISSING def module_spec_status(module_folder): if os.path.exists(os.path.join(module_folder, 'requirements', 'specification.reqif')): try: with open(os.path.join(module_folder, 'unittest', 'testresults', 'unittest.json'), 'r') as fh: ut = json.loads(fh.read()) if len(ut['lost_souls']['item_list']) > 0 or len(ut['lost_souls']['testcase_list']) > 0: return STATUS_IN_WORK else: return STATUS_CLEAN except IOError: return STATUS_EXISTS else: return STATUS_MISSING