def report_outcome(matches: List["MatchError"], options) -> int: """Display information about how to skip found rules. Returns exit code, 2 if erros were found, 0 when only warnings were found. """ failure = False msg = """\ You can skip specific rules by adding them to the skip_list section of your configuration file: ```yaml # .ansible-lint warn_list: # or 'skip_list' to silence them completely """ matched_rules = {match.rule.id: match.rule.shortdesc for match in matches} for id in sorted(matched_rules.keys()): if id not in options.warn_list: msg += f" - '{id}' # {matched_rules[id]}'\n" failure = True msg += "```" if failure: if not options.quiet and not options.parseable: console.print(Markdown(msg)) return 2 else: return 0
def render_matches(self, matches: List) -> None: """Display given matches.""" if isinstance(self.formatter, formatters.CodeclimateJSONFormatter): # If formatter CodeclimateJSONFormatter is chosen, # then print only the matches in JSON console.print( self.formatter.format_result(matches), markup=False, highlight=False ) return None ignored_matches = [match for match in matches if match.ignored] fatal_matches = [match for match in matches if not match.ignored] # Displayed ignored matches first if ignored_matches: _logger.warning( "Listing %s violation(s) marked as ignored, likely already known", len(ignored_matches), ) for match in ignored_matches: if match.ignored: # highlight must be off or apostrophes may produce unexpected results console.print(self.formatter.format(match), highlight=False) if fatal_matches: _logger.warning( "Listing %s violation(s) that are fatal", len(fatal_matches) ) for match in fatal_matches: if not match.ignored: console.print(self.formatter.format(match), highlight=False) # If run under GitHub Actions we also want to emit output recognized by it. if os.getenv('GITHUB_ACTIONS') == 'true' and os.getenv('GITHUB_WORKFLOW'): formatter = formatters.AnnotationsFormatter(self.options.cwd, True) for match in matches: console.print(formatter.format(match), markup=False, highlight=False)
def _render_matches( matches: List, options: "Namespace", formatter: Any, cwd: Union[str, pathlib.Path]): ignored_matches = [match for match in matches if match.ignored] fatal_matches = [match for match in matches if not match.ignored] # Displayed ignored matches first if ignored_matches: _logger.warning( "Listing %s violation(s) marked as ignored, likely already known", len(ignored_matches)) for match in ignored_matches: if match.ignored: # highlight must be off or apostrophes may produce unexpected results console.print( formatter.format(match), highlight=False) if fatal_matches: _logger.warning("Listing %s violation(s) that are fatal", len(fatal_matches)) for match in fatal_matches: if not match.ignored: console.print(formatter.format(match), highlight=False) # If run under GitHub Actions we also want to emit output recognized by it. if os.getenv('GITHUB_ACTIONS') == 'true' and os.getenv('GITHUB_WORKFLOW'): formatter = formatters.AnnotationsFormatter(cwd, True) for match in matches: console.print(formatter.format(match), markup=False, highlight=False)
def main(argv: Optional[List[str]] = None) -> int: """Linter CLI entry point.""" if argv is None: argv = sys.argv initialize_options(argv[1:]) console_options["force_terminal"] = options.colored reconfigure(console_options) initialize_logger(options.verbosity) _logger.debug("Options: %s", options) app = App(options=options) prepare_environment() check_ansible_presence(exit_on_error=True) # On purpose lazy-imports to avoid pre-loading Ansible # pylint: disable=import-outside-toplevel from ansiblelint.generate_docs import rules_as_rich, rules_as_rst, rules_as_str from ansiblelint.rules import RulesCollection rules = RulesCollection(options.rulesdirs) if options.listrules: _rule_format_map: Dict[str, Callable[..., Any]] = { 'plain': rules_as_str, 'rich': rules_as_rich, 'rst': rules_as_rst, } console.print(_rule_format_map[options.format](rules), highlight=False) return 0 if options.listtags: console.print(render_yaml(rules.listtags())) return 0 if isinstance(options.tags, str): options.tags = options.tags.split(',') from ansiblelint.runner import _get_matches result = _get_matches(rules, options) mark_as_success = False if result.matches and options.progressive: _logger.info( "Matches found, running again on previous revision in order to detect regressions" ) with _previous_revision(): old_result = _get_matches(rules, options) # remove old matches from current list matches_delta = list(set(result.matches) - set(old_result.matches)) if len(matches_delta) == 0: _logger.warning( "Total violations not increased since previous " "commit, will mark result as success. (%s -> %s)", len(old_result.matches), len(matches_delta), ) mark_as_success = True ignored = 0 for match in result.matches: # if match is not new, mark is as ignored if match not in matches_delta: match.ignored = True ignored += 1 if ignored: _logger.warning( "Marked %s previously known violation(s) as ignored due to" " progressive mode.", ignored, ) app.render_matches(result.matches) return report_outcome(result, mark_as_success=mark_as_success, options=options)
def main(argv: List[str] = None) -> int: """Linter CLI entry point.""" if argv is None: argv = sys.argv cwd = pathlib.Path.cwd() options = cli.get_config(argv[1:]) if options.colored is None: options.colored = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty() if options.colored is not None: console_options["force_terminal"] = options.colored reconfigure(console_options) initialize_logger(options.verbosity) _logger.debug("Options: %s", options) formatter_factory = choose_formatter_factory(options) formatter = formatter_factory(cwd, options.display_relative_path) rulesdirs = get_rules_dirs([str(rdir) for rdir in options.rulesdir], options.use_default_rules) rules = RulesCollection(rulesdirs) if options.listrules: console.print( _rule_format_map[options.format](rules), highlight=False) return 0 if options.listtags: console.print( render_yaml(rules.listtags()) ) return 0 if isinstance(options.tags, str): options.tags = options.tags.split(',') options.skip_list = _sanitize_list_options(options.skip_list) options.warn_list = _sanitize_list_options(options.warn_list) result = _get_matches(rules, options) mark_as_success = False if result.matches and options.progressive: _logger.info( "Matches found, running again on previous revision in order to detect regressions") with _previous_revision(): old_result = _get_matches(rules, options) # remove old matches from current list matches_delta = list(set(result.matches) - set(old_result.matches)) if len(matches_delta) == 0: _logger.warning( "Total violations not increased since previous " "commit, will mark result as success. (%s -> %s)", len(old_result.matches), len(matches_delta)) mark_as_success = True ignored = 0 for match in result.matches: # if match is not new, mark is as ignored if match not in matches_delta: match.ignored = True ignored += 1 if ignored: _logger.warning( "Marked %s previously known violation(s) as ignored due to" " progressive mode.", ignored) _render_matches(result.matches, options, formatter, cwd) return report_outcome(result, mark_as_success=mark_as_success, options=options)
def main() -> int: """Linter CLI entry point.""" cwd = pathlib.Path.cwd() options = cli.get_config(sys.argv[1:]) initialize_logger(options.verbosity) _logger.debug("Options: %s", options) formatter_factory = choose_formatter_factory(options) formatter = formatter_factory(cwd, options.display_relative_path) rulesdirs = get_rules_dirs([str(rdir) for rdir in options.rulesdir], options.use_default_rules) rules = RulesCollection(rulesdirs) if options.listrules: console.print(_rule_format_map[options.format](rules), highlight=False) return 0 if options.listtags: print(rules.listtags()) return 0 if isinstance(options.tags, str): options.tags = options.tags.split(',') skip = set() for s in options.skip_list: skip.update(str(s).split(',')) options.skip_list = frozenset(skip) if not options.playbook: # no args triggers auto-detection mode playbooks = get_playbooks_and_roles(options=options) else: playbooks = sorted(set(options.playbook)) matches = list() checked_files: Set[str] = set() for playbook in playbooks: runner = Runner(rules, playbook, options.tags, options.skip_list, options.exclude_paths, options.verbosity, checked_files) matches.extend(runner.run()) # Assure we do not print duplicates and the order is consistent matches = sorted(set(matches)) for match in matches: print(formatter.format(match, options.colored)) # If run under GitHub Actions we also want to emit output recognized by it. if os.getenv('GITHUB_ACTIONS') == 'true' and os.getenv('GITHUB_WORKFLOW'): formatter = formatters.AnnotationsFormatter(cwd, True) for match in matches: print(formatter.format(match)) if matches: return report_outcome(matches, options=options) else: return 0
def main() -> int: """Linter CLI entry point.""" cwd = pathlib.Path.cwd() options = cli.get_config(sys.argv[1:]) initialize_logger(options.verbosity) _logger.debug("Options: %s", options) formatter_factory = choose_formatter_factory(options) formatter = formatter_factory(cwd, options.display_relative_path) rulesdirs = get_rules_dirs([str(rdir) for rdir in options.rulesdir], options.use_default_rules) rules = RulesCollection(rulesdirs) if options.listrules: console.print(_rule_format_map[options.format](rules), highlight=False) return 0 if options.listtags: print(rules.listtags()) return 0 if isinstance(options.tags, str): options.tags = options.tags.split(',') skip = set() for s in options.skip_list: skip.update(str(s).split(',')) options.skip_list = frozenset(skip) matches = _get_matches(rules, options) # Assure we do not print duplicates and the order is consistent matches = sorted(set(matches)) mark_as_success = False if matches and options.progressive: _logger.info( "Matches found, running again on previous revision in order to detect regressions" ) with _previous_revision(): old_matches = _get_matches(rules, options) # remove old matches from current list matches_delta = list(set(matches) - set(old_matches)) if len(matches_delta) == 0: _logger.warning( "Total violations not increased since previous " "commit, will mark result as success. (%s -> %s)", len(old_matches), len(matches_delta)) mark_as_success = True ignored = 0 for match in matches: # if match is not new, mark is as ignored if match not in matches_delta: match.ignored = True ignored += 1 if ignored: _logger.warning( "Marked %s previously known violation(s) as ignored due to" " progressive mode.", ignored) _render_matches(matches, options, formatter, cwd) if matches and not mark_as_success: return report_outcome(matches, options=options) else: return 0