ldcheck.py

Sat, 08 Jun 2019 11:17:17 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Sat, 08 Jun 2019 11:17:17 +0300
changeset 65
f2dc17b830e0
parent 63
8949af6a4279
permissions
-rwxr-xr-x

cleanup

#!/usr/bin/env python3
'''
    Main LDCheck commandline program.
'''
from sys import version_info
if version_info < (3, 4):
    raise RuntimeError('Python 3.4 or newer required')

from geometry import *
import linetypes
import header
import parse
import config
import colours

def format_report(report, model):
    '''
        Formats the report from the test suite so as to be
        printed in the console.
    '''
    import colorama
    colorama.init()
    messages = []
    for problem in report['problems']:
        if problem.severity == 'hold':
            text_colour = colorama.Fore.LIGHTRED_EX
        elif problem.severity == 'warning':
            text_colour = colorama.Fore.LIGHTBLUE_EX
        else:
            text_colour = ''
        ldraw_code = model.body[problem.body_index].textual_representation()
        message = str.format(
            '{text_colour}{model_name}:{line_number}: {problem_type}: {message}'
            '{colour_reset}\n\t{ldraw_code}',
            text_colour = text_colour,
            model_name = model.name,
            line_number = problem.line_number,
            problem_type = problem.severity,
            message = str(problem),
            colour_reset = colorama.Fore.RESET,
            ldraw_code = ldraw_code,
        )
        messages.append(message)
    return '\n'.join(messages)

import argparse

class ListTestSuiteAction(argparse.Action):
    def __init__(self, option_strings, dest, nargs = None, **kwargs):
        super().__init__(option_strings, dest, nargs = 0, **kwargs)
    def __call__(self, *args, **kwargs):
        import testsuite
        from sys import exit
        from re import sub
        test_suite = testsuite.load_tests()
        for warning_type in testsuite.all_problem_types(test_suite):
            print(str.format('{name}: {severity}: "{message}"',
                name = warning_type.name,
                severity = warning_type.severity,
                message = warning_type.placeholder_message(),
            ))
        exit(0)

if __name__ == '__main__':
    from sys import argv
    parser = argparse.ArgumentParser()
    parser.add_argument('filename')
    parser.add_argument('--list',
        action = ListTestSuiteAction,
        help = 'Lists all possible checks and exit',
    )
    parser.add_argument('--dump-structure', action = 'store_true')
    parser.add_argument('--rebuild', action = 'store_true')
    parser.add_argument('--flatness', action = 'store_true')
    args = parser.parse_args()
    config_object = config.load_config('ldcheck.cfg')
    for ldconfig_ldr_path in config.find_ldconfig_ldr_paths(config_object):
        with ldconfig_ldr_path.open() as ldconfig_ldr:
            colours.load_colours(ldconfig_ldr)
    if args.flatness:
        import filecache
        cache = filecache.SubfileCache(
            ldraw_directories = config_object['libraries'],
        )
        subfile = cache.prepare_file(args.filename)
        if not subfile.valid:
            print(subfile.problem)
        else:
            if subfile.flatness:
                print(str.format(
                    'Flatness: {}',
                    ', '.join(subfile.flatness),
                ))
            else:
                print('File is not flat in any dimensions')
    else:
        with open(args.filename) as file:
            from os.path import basename
            model = parse.read_ldraw(
                file,
                name = basename(args.filename),
                ldraw_directories = config_object['libraries'])
            if args.dump_structure:
                print('header: ' + type(model.header).__name__)
                for key in sorted(dir(model.header)):
                    if not key.startswith('__'):
                        print('\t' + key + ': ' + repr(getattr(model.header, key)))
                for entry in model.body:
                    print(entry)
            elif args.rebuild:
                for entry in model.body:
                    print(entry.textual_representation(), end = '\r\n')
            else:
                import testsuite
                test_suite = testsuite.load_tests()
                report = testsuite.check_model(model, test_suite)
                print(format_report(report, model))

mercurial