def test_generate_config_parseable(test_dirs): """Ensure configuration produced by generate_config is parseable.""" config = initialization.generate_config(test_dirs) stream = BytesIO() stream.write(config.encode('utf-8')) stream.seek(0) assert parsing.load_config(stream)
def lint(modified_only=False, project_directory='.', verbose=False): """Lint project.""" config_path = os.path.abspath( os.path.join(project_directory, '.bellybutton.yml') ) try: with open(config_path, 'r') as f: rules = load_config(f) except IOError: message = "ERROR: Configuration file path `{}` does not exist." print(error(message.format(config_path))) return 1 except InvalidNode as e: message = "ERROR: {}, {}" exc_message = getattr(e, 'message', str(e)) print(error(message.format(config_path, exc_message))) return 1 if verbose: failure_message = dedent(""" \033[95m{path}:{lineno}\033[0m\t\033[1;95;4m{rule.name}\033[0m \033[1mDescription\033[0m: {rule.description} \033[1mLine\033[0m: {line} \033[1mExample\033[0m: {rule.example} \033[1mInstead\033[0m: {rule.instead} """).lstrip() else: failure_message = "{path}:{lineno}\t{rule.name}: {rule.description}" failures = 0 filepath_source = get_git_modified if modified_only else walk_python_files filepaths = list(filepath_source(os.path.abspath(project_directory))) for failure in linting_failures(filepaths, rules): failures += 1 print(failure_message.format( path=os.path.relpath(failure.path, project_directory), lineno=failure.lineno, line=failure.line, rule=failure.rule )) final_message = "Linting {} ({} rule{}, {} file{}, {} violation{}).".format( 'failed' if failures else 'succeeded', len(rules), '' if len(rules) == 1 else 's', len(filepaths), '' if len(filepaths) == 1 else 's', failures, '' if failures == 1 else 's', ) print((error if failures else success)(final_message)) return 1 if failures else 0
def test_loadable(file): """Ensure that bellybutton is able to parse configuration.""" with open(file, 'r') as f: assert isinstance(load_config(f), list)
def lint(modified_only=False, project_directory='.', verbose=False): """Lint project.""" config_path = os.path.abspath( os.path.join(project_directory, '.bellybutton.yml')) try: with open(config_path, 'r') as f: rules = load_config(f) except IOError: message = "ERROR: Configuration file path `{}` does not exist." print(error(message.format(config_path))) return 1 except InvalidNode as e: message = "ERROR: When parsing {}: {!r}" print(error(message.format(config_path, e))) return 1 if verbose: failure_message = dedent(""" \033[95m{path}:{lineno}\033[0m\t\033[1;95;4m{rule.name}\033[0m \033[1mDescription\033[0m: {rule.description} \033[1mLine\033[0m: {line} \033[1mExample\033[0m: {rule.example} \033[1mInstead\033[0m: {rule.instead} """).lstrip() else: failure_message = "{path}:{lineno}\t{rule.name}: {rule.description}" num_files = 0 failures = 0 files = walk_python_files(os.path.abspath(project_directory)) for filepath, file_contents in files: relpath = os.path.relpath(filepath, project_directory) linting_results = list(lint_file(filepath, file_contents, rules)) if not linting_results: continue num_files += 1 failure_results = (result for result in linting_results if not result.succeeded) for failure in failure_results: failures += 1 print( failure_message.format( path=relpath, lineno=failure.lineno, line=file_contents.splitlines()[failure.lineno - 1], rule=failure.rule, )) final_message = "Linting {} ({} rule{}, {} file{}, {} violation{}).".format( 'failed' if failures else 'succeeded', len(rules), '' if len(rules) == 1 else 's', num_files, '' if num_files == 1 else 's', failures, '' if failures == 1 else 's', ) print((error if failures else success)(final_message)) return 1 if failures else 0