1"""Pylama's shell support.""" 2 3from __future__ import absolute_import, with_statement 4 5import sys 6from os import walk, path as op 7 8from .config import parse_options, CURDIR, setup_logger 9from .core import LOGGER, run 10from .check_async import check_async 11 12 13def check_path(options, rootdir=None, candidates=None, code=None): 14 """Check path. 15 16 :param rootdir: Root directory (for making relative file paths) 17 :param options: Parsed pylama options (from pylama.config.parse_options) 18 19 :returns: (list) Errors list 20 21 """ 22 if not candidates: 23 candidates = [] 24 for path_ in options.paths: 25 path = op.abspath(path_) 26 if op.isdir(path): 27 for root, _, files in walk(path): 28 candidates += [op.relpath(op.join(root, f), CURDIR) 29 for f in files] 30 else: 31 candidates.append(path) 32 33 if rootdir is None: 34 rootdir = path if op.isdir(path) else op.dirname(path) 35 36 paths = [] 37 for path in candidates: 38 39 if not options.force and not any(l.allow(path) 40 for _, l in options.linters): 41 continue 42 43 if not op.exists(path): 44 continue 45 46 paths.append(path) 47 48 if options.concurrent: 49 return check_async(paths, options, rootdir) 50 51 errors = [] 52 for path in paths: 53 errors += run(path=path, code=code, rootdir=rootdir, options=options) 54 return errors 55 56 57def shell(args=None, error=True): 58 """Endpoint for console. 59 60 Parse a command arguments, configuration files and run a checkers. 61 62 :return list: list of errors 63 :raise SystemExit: 64 65 """ 66 if args is None: 67 args = sys.argv[1:] 68 69 options = parse_options(args) 70 setup_logger(options) 71 LOGGER.info(options) 72 73 # Install VSC hook 74 if options.hook: 75 from .hook import install_hook 76 for path in options.paths: 77 return install_hook(path) 78 79 return process_paths(options, error=error) 80 81 82def process_paths(options, candidates=None, error=True): 83 """Process files and log errors.""" 84 errors = check_path(options, rootdir=CURDIR, candidates=candidates) 85 86 if options.format in ['pycodestyle', 'pep8']: 87 pattern = "%(filename)s:%(lnum)s:%(col)s: %(text)s" 88 elif options.format == 'pylint': 89 pattern = "%(filename)s:%(lnum)s: [%(type)s] %(text)s" 90 else: # 'parsable' 91 pattern = "%(filename)s:%(lnum)s:%(col)s: [%(type)s] %(text)s" 92 93 for er in errors: 94 if options.abspath: 95 er._info['filename'] = op.abspath(er.filename) 96 LOGGER.warning(pattern, er._info) 97 98 if error: 99 sys.exit(int(bool(errors))) 100 101 return errors 102 103 104if __name__ == '__main__': 105 shell() 106 107# pylama:ignore=F0001 108