Thu, 26 Aug 2021 19:36:44 +0300
Merge commit
colours.py | file | annotate | diff | comparison | revisions | |
ldcheck.py | file | annotate | diff | comparison | revisions |
--- a/colours.py Fri Sep 18 23:51:45 2020 +0300 +++ b/colours.py Thu Aug 26 19:36:44 2021 +0300 @@ -75,19 +75,9 @@ colour = parse_ldconfig_ldr_line(line) yield (colour['code'], colour) - def load_colours(ldconfig_ldr): ''' Loads colours. Expects a file pointer to LDConfig.ldr as the parameter. Returns a lookup table ''' - ldconfig_colour_data = dict(parse_ldconfig_ldr(ldconfig_ldr)) - for index, colour in ldconfig_colour_data.items(): - identifier = colour['name'].replace(' ', '_').lower() - return ldconfig_colour_data - -# Interactive mode support (pass LDConfig.ldr path as a command-line argument) -if __name__ == '__main__': - from sys import argv - with open(argv[1]) as ldconfig_ldr: - load_colours(ldconfig_ldr) + return dict(parse_ldconfig_ldr(ldconfig_ldr))
--- a/ldcheck.py Fri Sep 18 23:51:45 2020 +0300 +++ b/ldcheck.py Thu Aug 26 19:36:44 2021 +0300 @@ -1,19 +1,58 @@ #!/usr/bin/env python3 +<<<<<<< /home/teemu/dev/ldcheck/ldcheck.py +import sys +if sys.version_info < (3, 4): +======= import argparse from sys import version_info if version_info < (3, 4): +>>>>>>> /tmp/ldcheck~other.ou_xbg_k.py raise RuntimeError('Python 3.4 or newer required') +<<<<<<< /home/teemu/dev/ldcheck/ldcheck.py +from colours import load_colours +======= appname = 'ldcheck' version = (1, 0, 9999) version_string = str.join('.', map(str, version)) +>>>>>>> /tmp/ldcheck~other.ou_xbg_k.py from geometry import * from pathlib import Path import linetypes import header import parse +<<<<<<< /home/teemu/dev/ldcheck/ldcheck.py +def check_library_paths(library_paths): + for library_path in library_paths: + if not library_path.exists(): + raise RuntimeError(str.format( + 'error: library path {} does not exist', + library_path, + )) + elif not library_path.exists(): + raise RuntimeError(str.format( + 'error: library path {} is not a directory', + library_path, + )) + +def find_ldconfig_ldr_paths(libraries): + for library_path in libraries: + yield from [ + library_path / path + for path in ['LDConfig.ldr', 'ldconfig.ldr'] + if (library_path / path).is_file() + ] + +def load_ldconfig(libraries): + ldconfig_ldr_paths = list(find_ldconfig_ldr_paths(libraries)) + if not ldconfig_ldr_paths: + raise RuntimeError('could not find any LDConfig.ldr') + for ldconfig_ldr_path in ldconfig_ldr_paths: + with ldconfig_ldr_path.open() as ldconfig_ldr: + load_colours(ldconfig_ldr) +======= from os.path import realpath script_directory = Path(realpath(__file__)).parent @@ -108,7 +147,32 @@ return '#000000' def is_valid_colour(self, colour): return self.is_ldconfig_colour(colour) or colour.is_direct_colour +>>>>>>> /tmp/ldcheck~other.ou_xbg_k.py +<<<<<<< /home/teemu/dev/ldcheck/ldcheck.py +def parse_commandline_arguments(): + import os + rcpath = Path(os.path.expanduser('~/.config/ldcheckrc')) + if rcpath.exists(): + with rcpath.open() as file: + rcargs = ['--' + line.strip() for line in file] + else: + rcargs = [] + import argparse + class ListProblemTypesAction(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 + 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(), + )) + sys.exit(0) +======= class ListProblemsAction(argparse.Action): def __init__(self, option_strings, dest, nargs = None, **kwargs): super().__init__(option_strings, dest, nargs = 0, **kwargs) @@ -152,10 +216,11 @@ if __name__ == '__main__': from sys import argv, stderr, exit +>>>>>>> /tmp/ldcheck~other.ou_xbg_k.py parser = argparse.ArgumentParser() parser.add_argument('filename') parser.add_argument('--list', - action = ListProblemsAction, + action = ListProblemTypesAction, help = 'lists all possible problem types and exit', ) parser.add_argument('--dump', @@ -171,6 +236,26 @@ action = 'store_true', help = 'finds a subfile by name and prints out information about it' ) +<<<<<<< /home/teemu/dev/ldcheck/ldcheck.py + parser.add_argument('-l', '--library', action = 'append') + arglist = rcargs + sys.argv[1:] + return parser.parse_args(arglist) + +def main(): + args = parse_commandline_arguments() + # Make sure that we have at least one library path specified. + if not args.library: + raise RuntimeError( + 'Please specify libraries using the -l / --library switch.\n' + 'For example: -l ~/ldraw or --library=~/ldraw\n' + 'Multiple --library switches may be used.') + # Prepare the list of libraries. This also expands the ~ for the home + # directory + import os + libraries = [Path(os.path.expanduser(library)) for library in args.library] + check_library_paths(libraries) + load_ldconfig(libraries) +======= parser.add_argument('--color', action = 'store_true', help = 'use colors' @@ -202,9 +287,17 @@ except ImportError: print('Use of --color requires the colorama module, disabling colours', file = stderr) args.color = False +>>>>>>> /tmp/ldcheck~other.ou_xbg_k.py if args.subfile: + # Subfile debug mode: searches for the specified subfile from the LDraw + # libraries, opens it as if it was referenced by something and prints + # out all information that is calculated from this subfile. import filecache +<<<<<<< /home/teemu/dev/ldcheck/ldcheck.py + cache = filecache.SubfileCache(ldraw_directories = libraries) +======= cache = filecache.SubfileCache(context = context) +>>>>>>> /tmp/ldcheck~other.ou_xbg_k.py subfile = cache.prepare_file(args.filename) if not subfile.valid: print(subfile.problem) @@ -213,6 +306,51 @@ print('Description:', repr(subfile.description)) print('Contains studs:', repr(subfile.has_studs)) else: +<<<<<<< /home/teemu/dev/ldcheck/ldcheck.py + with open(args.filename, 'rb') as file: + from os.path import basename + model = parse.read_ldraw( + file, + name = basename(args.filename), + ldraw_directories = libraries) + if args.dump: + # Dump mode: prints out the structure of the processed LDraw file + 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 i, entry in enumerate(model.body): + if model.header.valid and i == model.header_size: + # Mark where the header is considered to end + print('--------- End of header') + print(entry) + elif args.rebuild: + # Debug rebuild mode: open the file, parse it and turn it back + # into LDraw code and write it into stdout. This is used to ensure + # that LDCheck does not miss any information while parsing files. + for entry in model.body: + print(entry.textual_representation(), end = '\r\n') + else: + # Regular mode + from testsuite import load_tests, check_model, format_report + # load the test suite + # TODO: maybe add some command line argument to filter tests + # in case the user wants to run some specific tests only or + # possibly leave some test out + test_suite = load_tests() + # use the test suite to check the model + report = check_model(model, test_suite) + # print out the report + print(format_report(report, model, test_suite)) + +if __name__ == '__main__': + try: + main() + except RuntimeError as e: + import sys + print('error:', str(e), file = sys.stderr) + sys.exit(1) +======= try: with open(args.filename, 'rb') as file: from os.path import basename @@ -248,3 +386,4 @@ filename = args.filename ), file = stderr) exit(1) +>>>>>>> /tmp/ldcheck~other.ou_xbg_k.py