示例#1
0
def generate_capabilities_map(bears_by_lang):
    """
    Generates a dictionary of capabilities, languages and the
    corresponding bears from the given ``bears_by_lang`` dict.

    :param bears_by_lang: dict with language names as keys
                          and the list of bears as values.
    :returns:             dict of the form
                          {
                            "language": {
                                "detect": [list, of, bears]
                                "fix": [list, of, bears]
                            }
                          }
    """
    def nested_dict():
        return defaultdict(dict)

    capabilities_meta = defaultdict(nested_dict)

    # collectiong the capabilities meta-data
    for lang, bears in bears_by_lang.items():
        can_detect_meta = inverse_dicts(*[{
            bear: list(bear.CAN_DETECT)
        } for bear in bears])
        can_fix_meta = inverse_dicts(*[{
            bear: list(bear.CAN_FIX)
        } for bear in bears])

        for capability, bears in can_detect_meta.items():
            capabilities_meta[capability][lang]['DETECT'] = bears

        for capability, bears in can_fix_meta.items():
            capabilities_meta[capability][lang]['FIX'] = bears
    return capabilities_meta
示例#2
0
def generate_capabilties_map(bears_by_lang):
    """
    Generates a dictionary of capabilities, languages and the
    corresponding bears from the given ``bears_by_lang`` dict.

    :param bears_by_lang: dict with language names as keys
                          and the list of bears as values.
    :returns:             dict of the form
                          {
                            "language": {
                                "detect": [list, of, bears]
                                "fix": [list, of, bears]
                            }
                          }
    """

    def nested_dict():
        return defaultdict(dict)
    capabilities_meta = defaultdict(nested_dict)

    # collectiong the capabilities meta-data
    for lang, bears in bears_by_lang.items():
        can_detect_meta = inverse_dicts(
            *[{bear: list(bear.CAN_DETECT)} for bear in bears])
        can_fix_meta = inverse_dicts(
            *[{bear: list(bear.CAN_FIX)} for bear in bears])

        for capability, bears in can_detect_meta.items():
            capabilities_meta[capability][lang]['DETECT'] = bears

        for capability, bears in can_fix_meta.items():
            capabilities_meta[capability][lang]['FIX'] = bears
    return capabilities_meta
示例#3
0
def mode_json(args, debug=False):
    import json

    from coalib.coala_main import run_coala
    from coalib.misc.DictUtilities import inverse_dicts
    from coalib.misc.Exceptions import get_exitcode
    from coalib.output.Logging import configure_json_logging
    from coalib.output.JSONEncoder import create_json_encoder

    if args.log_json:
        log_stream = configure_json_logging()

    JSONEncoder = create_json_encoder(use_relpath=args.relpath)
    results = []

    if args.show_bears:
        try:
            from coalib.parsing.FilterHelper import FilterHelper

            local_bears, global_bears = FilterHelper.apply_filter(
                'language', args.filter_by_language)
            bears = inverse_dicts(local_bears, global_bears)
            for bear, _ in sorted(bears.items(),
                                  key=lambda bear_tuple: bear_tuple[0].name):
                results.append(bear)
        except BaseException as exception:  # pylint: disable=broad-except
            return get_exitcode(exception)
    else:
        results, exitcode, _ = run_coala(args=args, debug=debug)

    retval = {'bears': results} if args.show_bears else {'results': results}

    if args.log_json:
        retval['logs'] = [
            json.loads(line) for line in log_stream.getvalue().splitlines()
        ]

    if args.output:
        filename = str(args.output[0])
        with open(filename, 'w+') as fp:
            json.dump(retval,
                      fp,
                      cls=JSONEncoder,
                      sort_keys=True,
                      indent=2,
                      separators=(',', ': '))
    else:
        print(
            json.dumps(retval,
                       cls=JSONEncoder,
                       sort_keys=True,
                       indent=2,
                       separators=(',', ': ')))

    return 0 if args.show_bears else exitcode
示例#4
0
    def test_inverse_dicts(self):
        self.dict1 = {1: [1, 2, 3], 2: [3, 4, 5]}
        self.dict2 = {2: [1], 3: [2], 4: [3, 4]}
        self.dict3 = {1: 2, 3: 4, 4: 4, 5: 4}
        self.dict4 = {2: 3, 4: 4}
        result = inverse_dicts(self.dict3)
        self.assertEqual({2: [1], 4: [3, 4, 5]}, result)

        result = inverse_dicts(self.dict1)
        self.assertEqual({1: [1], 2: [1], 3: [1, 2], 4: [2], 5: [2]}, result)

        result = inverse_dicts(self.dict3, self.dict4)
        self.assertEqual({2: [1], 3: [2], 4: [3, 4, 5, 4]}, result)

        result = inverse_dicts(self.dict1, self.dict2)
        self.assertEqual({1: [1, 2],
                          2: [1, 3],
                          3: [1, 2, 4],
                          4: [2, 4],
                          5: [2]}, result)
def get_bears():
    """
    Get a dict of bears with the bear class as key.

    :return:
        A dict with bear classes as key and the list of sections
        as value.
    """
    log_printer = LogPrinter(NullPrinter())
    sections, _ = load_configuration(None, log_printer)
    local_bears, global_bears = collect_all_bears_from_sections(
        sections, log_printer)
    return inverse_dicts(local_bears, global_bears)
示例#6
0
def main():
    # Note: We parse the args here once to find the log printer to use.
    #       Also, commands like -h (help) and -v (version) are executed here.
    #       The args are again parsed later to find the settings and configs
    #       to use during analysis.
    arg_parser = default_arg_parser()
    args = arg_parser.parse_args()

    log_printer = None if args.text_logs else ListLogPrinter()
    JSONEncoder = create_json_encoder(use_relpath=args.relpath)
    results = []

    if args.show_bears:
        try:
            local_bears, global_bears = get_filtered_bears(
                args.filter_by_language, log_printer)
            bears = inverse_dicts(local_bears, global_bears)
            for bear, _ in sorted(bears.items(),
                                  key=lambda bear_tuple: bear_tuple[0].name):
                results.append(bear)
        except BaseException as exception:  # pylint: disable=broad-except
            return get_exitcode(exception, log_printer)
    else:
        results, exitcode, _ = run_coala(log_printer=log_printer,
                                         autoapply=False)

    retval = {"bears": results} if args.show_bears else {"results": results}
    if not args.text_logs:
        retval["logs"] = log_printer.logs
    if args.output:
        filename = str(args.output[0])
        with open(filename, 'w+') as fp:
            json.dump(retval,
                      fp,
                      cls=JSONEncoder,
                      sort_keys=True,
                      indent=2,
                      separators=(',', ': '))
    else:
        print(
            json.dumps(retval,
                       cls=JSONEncoder,
                       sort_keys=True,
                       indent=2,
                       separators=(',', ': ')))

    return 0 if args.show_bears else exitcode
示例#7
0
def main():
    # Note: We parse the args here once to find the log printer to use.
    #       Also, commands like -h (help) and -v (version) are executed here.
    #       The args are again parsed later to find the settings and configs
    #       to use during analysis.
    arg_parser = default_arg_parser()
    args = arg_parser.parse_args()

    log_printer = None if args.text_logs else ListLogPrinter()
    JSONEncoder = create_json_encoder(use_relpath=args.relpath)
    results = []

    if args.show_bears:
        try:
            local_bears, global_bears = get_filtered_bears(
                args.filter_by_language, log_printer)
            bears = inverse_dicts(local_bears, global_bears)
            for bear, _ in sorted(bears.items(),
                                  key=lambda bear_tuple:
                                  bear_tuple[0].name):
                results.append(bear)
        except BaseException as exception:  # pylint: disable=broad-except
            return get_exitcode(exception, log_printer)
    else:
        results, exitcode, _ = run_coala(
            log_printer=log_printer, autoapply=False)

    retval = {"bears": results} if args.show_bears else {"results": results}
    if not args.text_logs:
        retval["logs"] = log_printer.logs
    if args.output:
        filename = str(args.output[0])
        with open(filename, 'w+') as fp:
            json.dump(retval, fp,
                      cls=JSONEncoder,
                      sort_keys=True,
                      indent=2,
                      separators=(',', ': '))
    else:
        print(json.dumps(retval,
                         cls=JSONEncoder,
                         sort_keys=True,
                         indent=2,
                         separators=(',', ': ')))

    return 0 if args.show_bears else exitcode
示例#8
0
def show_bears(local_bears, global_bears, console_printer):
    """
    Extracts all the bears from each enabled section or the sections in the
    targets and passes a dictionary to the show_bears_callback method.

    :param local_bears:         Dictionary of local bears with section names
                                as keys and bear list as values.
    :param global_bears:        Dictionary of global bears with section
                                names as keys and bear list as values.
    :param show_bears_callback: The callback that is used to print these
                                bears. It will get one parameter holding
                                bears as key and the list of section names
                                where it's used as values.
    """
    bears = inverse_dicts(local_bears, global_bears)

    print_bears(console_printer, bears)
示例#9
0
def mode_json(args):
    import json

    from coalib.coala_main import run_coala
    from coalib.misc.DictUtilities import inverse_dicts
    from coalib.misc.Exceptions import get_exitcode
    from coalib.output.JSONEncoder import create_json_encoder
    from coalib.output.printers.LogPrinter import LogPrinter
    from coalib.parsing.DefaultArgParser import default_arg_parser
    from coalib.settings.ConfigurationGathering import get_filtered_bears

    JSONEncoder = create_json_encoder(use_relpath=args.relpath)
    results = []

    if args.show_bears:
        try:
            local_bears, global_bears = get_filtered_bears(
                args.filter_by_language, LogPrinter())
            bears = inverse_dicts(local_bears, global_bears)
            for bear, _ in sorted(bears.items(),
                                  key=lambda bear_tuple:
                                  bear_tuple[0].name):
                results.append(bear)
        except BaseException as exception:  # pylint: disable=broad-except
            return get_exitcode(exception)
    else:
        results, exitcode, _ = run_coala()

    retval = {'bears': results} if args.show_bears else {'results': results}
    if args.output:
        filename = str(args.output[0])
        with open(filename, 'w+') as fp:
            json.dump(retval, fp,
                      cls=JSONEncoder,
                      sort_keys=True,
                      indent=2,
                      separators=(',', ': '))
    else:
        print(json.dumps(retval,
                         cls=JSONEncoder,
                         sort_keys=True,
                         indent=2,
                         separators=(',', ': ')))

    return 0 if args.show_bears else exitcode
示例#10
0
def mode_json(args):
    import json

    from coalib.coala_main import run_coala
    from coalib.misc.DictUtilities import inverse_dicts
    from coalib.misc.Exceptions import get_exitcode
    from coalib.output.JSONEncoder import create_json_encoder
    from coalib.output.printers.LogPrinter import LogPrinter
    from coalib.settings.ConfigurationGathering import get_filtered_bears

    JSONEncoder = create_json_encoder(use_relpath=args.relpath)
    results = []

    if args.show_bears:
        try:
            local_bears, global_bears = get_filtered_bears(
                args.filter_by_language, LogPrinter())
            bears = inverse_dicts(local_bears, global_bears)
            for bear, _ in sorted(bears.items(),
                                  key=lambda bear_tuple: bear_tuple[0].name):
                results.append(bear)
        except BaseException as exception:  # pylint: disable=broad-except
            return get_exitcode(exception)
    else:
        results, exitcode, _ = run_coala()

    retval = {'bears': results} if args.show_bears else {'results': results}
    if args.output:
        filename = str(args.output[0])
        with open(filename, 'w+') as fp:
            json.dump(retval,
                      fp,
                      cls=JSONEncoder,
                      sort_keys=True,
                      indent=2,
                      separators=(',', ': '))
    else:
        print(
            json.dumps(retval,
                       cls=JSONEncoder,
                       sort_keys=True,
                       indent=2,
                       separators=(',', ': ')))

    return 0 if args.show_bears else exitcode
示例#11
0
def show_bears(local_bears, global_bears, show_description, show_params, console_printer):
    """
    Extracts all the bears from each enabled section or the sections in the
    targets and passes a dictionary to the show_bears_callback method.

    :param local_bears:      Dictionary of local bears with section names
                             as keys and bear list as values.
    :param global_bears:     Dictionary of global bears with section
                             names as keys and bear list as values.
    :param show_description: True if the main description of the bears should
                             be shown.
    :param show_params:      True if the parameters and their description
                             should be shown.
    :param console_printer:  Object to print messages on the console.
    """
    bears = inverse_dicts(local_bears, global_bears)

    print_bears(bears, show_description, show_params, console_printer)
示例#12
0
def show_bears(local_bears, global_bears, show_description, show_params,
               console_printer):
    """
    Extracts all the bears from each enabled section or the sections in the
    targets and passes a dictionary to the show_bears_callback method.

    :param local_bears:      Dictionary of local bears with section names
                             as keys and bear list as values.
    :param global_bears:     Dictionary of global bears with section
                             names as keys and bear list as values.
    :param show_description: True if the main description of the bears should
                             be shown.
    :param show_params:      True if the parameters and their description
                             should be shown.
    :param console_printer:  Object to print messages on the console.
    """
    bears = inverse_dicts(local_bears, global_bears)

    print_bears(bears, show_description, show_params, console_printer)
示例#13
0
def show_bears(local_bears, global_bears, compress, console_printer):
    """
    Extracts all the bears from each enabled section or the sections in the
    targets and passes a dictionary to the show_bears_callback method.

    :param local_bears:         Dictionary of local bears with section names
                                as keys and bear list as values.
    :param global_bears:        Dictionary of global bears with section
                                names as keys and bear list as values.
    :param compress:            If set to true, output will be compressed (just
                                show bear names as a list)
    :param show_bears_callback: The callback that is used to print these
                                bears. It will get one parameter holding
                                bears as key and the list of section names
                                where it's used as values.
    """
    bears = inverse_dicts(local_bears, global_bears)

    print_bears(console_printer, bears, compress)
示例#14
0
def mode_json(args):
    import json

    from coalib.coala_main import run_coala
    from coalib.misc.DictUtilities import inverse_dicts
    from coalib.misc.Exceptions import get_exitcode
    from coalib.output.Logging import configure_json_logging
    from coalib.output.JSONEncoder import create_json_encoder
    from coalib.output.printers.LogPrinter import LogPrinter
    from coalib.settings.ConfigurationGathering import get_filtered_bears

    if args.log_json:
        log_stream = configure_json_logging()

    JSONEncoder = create_json_encoder(use_relpath=args.relpath)
    results = []

    if args.show_bears:
        try:
            local_bears, global_bears = get_filtered_bears(args.filter_by_language, LogPrinter())
            bears = inverse_dicts(local_bears, global_bears)
            for bear, _ in sorted(bears.items(), key=lambda bear_tuple: bear_tuple[0].name):
                results.append(bear)
        except BaseException as exception:  # pylint: disable=broad-except
            return get_exitcode(exception)
    else:
        results, exitcode, _ = run_coala()

    retval = {"bears": results} if args.show_bears else {"results": results}

    if args.log_json:
        retval["logs"] = [json.loads(line) for line in log_stream.getvalue().splitlines()]

    if args.output:
        filename = str(args.output[0])
        with open(filename, "w+") as fp:
            json.dump(retval, fp, cls=JSONEncoder, sort_keys=True, indent=2, separators=(",", ": "))
    else:
        print(json.dumps(retval, cls=JSONEncoder, sort_keys=True, indent=2, separators=(",", ": ")))

    return 0 if args.show_bears else exitcode
def show_bears(local_bears,
               global_bears,
               show_description,
               show_params,
               console_printer,
               args=None):
    """
    Extracts all the bears from each enabled section or the sections in the
    targets and passes a dictionary to the show_bears_callback method.
    :param local_bears:      Dictionary of local bears with section names
                             as keys and bear list as values.
    :param global_bears:     Dictionary of global bears with section
                             names as keys and bear list as values.
    :param show_description: This parameter is deprecated.
    :param show_params:      This parameter is deprecated.
    :param console_printer:  Object to print messages on the console.
    :param args:             Args passed to coala command.
    """
    bears = inverse_dicts(local_bears, global_bears)

    print_bears(bears, show_description, show_params, console_printer, args)
示例#16
0
def filter_relevant_bears(used_languages, arg_parser=None):
    """
    From the bear dict, filter the bears per relevant language.

    :param used_languages:
        A list of tuples with language name as the first element
        and percentage usage as the second element; sorted by
        percentage usage.
    :return:
        A dict with language name as key and bear classes as value.
    """
    log_printer = LogPrinter(NullPrinter())
    used_languages.append(("All", 100))

    all_bears_by_lang = {
        lang: set(
            inverse_dicts(
                *get_filtered_bears([lang], log_printer, arg_parser)).keys())
        for lang, _ in used_languages
    }

    bears_by_lang = {}
    for lang in all_bears_by_lang:
        if lang in IMPORTANT_BEAR_LIST:
            bears_by_lang[lang] = {
                bear
                for bear in all_bears_by_lang[lang]
                if bear.name in IMPORTANT_BEAR_LIST[lang]
            }
        else:
            bears_by_lang[lang] = all_bears_by_lang[lang]

    # Each language would also have the language independent bears. We remove
    # those and put them in the "All" category.
    lang_bears = {
        lang: bears_by_lang[lang] - bears_by_lang["All"]
        for lang, _ in used_languages
    }
    lang_bears["All"] = bears_by_lang["All"]
    return lang_bears
示例#17
0
def show_bears(local_bears,
               global_bears,
               show_description,
               show_params,
               console_printer,
               args=None):
    """
    Extracts all the bears from each enabled section or the sections in the
    targets and passes a dictionary to the show_bears_callback method.

    :param local_bears:      Dictionary of local bears with section names
                             as keys and bear list as values.
    :param global_bears:     Dictionary of global bears with section
                             names as keys and bear list as values.
    :param show_description: This parameter is deprecated.
    :param show_params:      This parameter is deprecated.
    :param console_printer:  Object to print messages on the console.
    :param args:             Args passed to coala command.
    """
    bears = inverse_dicts(local_bears, global_bears)

    print_bears(bears, show_description, show_params, console_printer, args)
示例#18
0
def filter_relevant_bears(used_languages):
    """
    From the bear dict, filter the bears per relevant language.

    :param used_languages:
        A list of tuples with language name as the first element
        and percentage usage as the second element; sorted by
        percentage usage.
    :return:
        A dict with language name as key and bear classes as value.
    """
    log_printer = LogPrinter(NullPrinter())
    used_languages.append(("All", 100))

    bears_by_lang = {lang: set(inverse_dicts(*get_filtered_bears(
        [lang], log_printer)).keys()) for lang, _ in used_languages}

    # Each language would also have the language independent bears. We remove
    # those and put them in the "All" category.
    lang_bears = {lang: bears_by_lang[lang] - bears_by_lang["All"]
                  for lang, _ in used_languages}
    lang_bears["All"] = bears_by_lang["All"]
    return lang_bears
示例#19
0
def filter_relevant_bears(used_languages,
                          printer,
                          arg_parser,
                          extracted_info,
                          log_printer=None):
    """
    From the bear dict, filter the bears per relevant language.

    :param used_languages:
        A list of tuples with language name as the first element
        and percentage usage as the second element; sorted by
        percentage usage.
    :param printer:
        ``ConsolePrinter`` object to be used for console interactions.
    :param arg_parser:
        ``argparse.ArgumentParser`` object containing the arguments
        passed.
    :param extracted_info:
        list of information extracted from ``InfoExtractor`` classes.
    :return:
        A dict with language name as key and bear classes as value.
    """
    args = arg_parser.parse_args() if arg_parser else None
    used_languages.append(('All', 100))

    bears_by_lang = {
        lang: set(inverse_dicts(*get_filtered_bears([lang],
                                                    log_printer,
                                                    arg_parser,
                                                    silent=True)).keys())
        for lang, _ in used_languages
    }

    # Each language would also have the language independent bears. We remove
    # those and put them in the "All" category.
    all_lang_bears = bears_by_lang['All']
    bears_by_lang = {lang: bears_by_lang[lang] - bears_by_lang['All']
                     for lang, _ in used_languages}
    bears_by_lang['All'] = all_lang_bears

    selected_bears = {}
    candidate_bears = copy.copy(bears_by_lang)
    to_propose_bears = {}

    REQUIRED_BEAR_LIST = IMPORTANT_BEAR_LIST

    if args.green_mode:
        from coala_quickstart.Constants import (
            GREEN_MODE_COMPATIBLE_BEAR_LIST,
            GREEN_MODE_INCOMPATIBLE_BEAR_LIST,
            )
        REQUIRED_BEAR_LIST = concatenate(IMPORTANT_BEAR_LIST,
                                         GREEN_MODE_COMPATIBLE_BEAR_LIST)
        NEW_REQUIRED_BEAR_LIST = {}
        for lang in REQUIRED_BEAR_LIST:
            NEW_REQUIRED_BEAR_LIST[lang] = set()
            for bear in REQUIRED_BEAR_LIST[lang]:
                if bear not in GREEN_MODE_INCOMPATIBLE_BEAR_LIST:
                    NEW_REQUIRED_BEAR_LIST[lang].add(bear)
        REQUIRED_BEAR_LIST = NEW_REQUIRED_BEAR_LIST

    # Initialize selected_bears with REQUIRED_BEAR_LIST
    for lang, lang_bears in candidate_bears.items():
        if lang_bears and lang in REQUIRED_BEAR_LIST:
            selected_bears[lang] = set()
            for bear in lang_bears:
                if bear.__name__ in REQUIRED_BEAR_LIST[lang]:
                    selected_bears[lang].add(bear)
        if lang_bears and lang not in REQUIRED_BEAR_LIST and (
                not args.green_mode):
            selected_bears[lang] = set(lang_bears)

        candidate_bears[lang] = set(
            [bear for bear in lang_bears
             if lang in selected_bears and
             bear not in selected_bears[lang]])

    if args.green_mode:
        return selected_bears

    if not args.no_filter_by_capabilities:
        # Ask user for capablities
        user_selected_capabilities = set()
        if not args.non_interactive:
            user_selected_capabilities = ask_to_select_capabilties(
                list(ALL_CAPABILITIES), list(DEFAULT_CAPABILTIES), printer)

        desired_capabilities = (
            user_selected_capabilities if user_selected_capabilities
            else DEFAULT_CAPABILTIES)

        # Filter bears based on capabilties
        for lang, lang_bears in candidate_bears.items():
            # Eliminate bears which doesn't contain the desired capabilites
            capable_bears = get_bears_with_given_capabilities(
                lang_bears, desired_capabilities)
            candidate_bears[lang] = capable_bears

    lint_task_info = extracted_info.get('LintTaskInfo', [])
    project_dependency_info = extracted_info.get('ProjectDependencyInfo', [])

    # Use lint_task_info to propose bears to user.
    for lang, lang_bears in candidate_bears.items():
        matching_linter_bears = get_matching_linter_bears(
                lang_bears, lint_task_info)
        to_propose_bears[lang] = matching_linter_bears

    # Use project_dependency_info to propose bears to user.
    for lang, lang_bears in candidate_bears.items():
        matching_dep_bears = get_bears_with_matching_dependencies(
            lang_bears, project_dependency_info)
        if to_propose_bears.get(lang):
            to_propose_bears[lang].update(matching_dep_bears)
        else:
            to_propose_bears[lang] = matching_dep_bears

    for lang, lang_bears in to_propose_bears.items():
        for bear in lang_bears:
            # get the non-optional settings of the bears
            settings = bear.get_non_optional_settings()
            if settings:
                user_input_reqd = False
                for setting in settings:
                    if not is_autofill_possible(
                            setting, lang, bear, extracted_info):
                        user_input_reqd = True
                        break

                if user_input_reqd:
                    # Ask user to activate the bear
                    if (args and not args.non_interactive and
                            prompt_to_activate(bear, printer)):
                        selected_bears[lang].add(bear)
                else:
                    # All the non-optional settings can be filled automatically
                    selected_bears[lang].add(bear)
            else:
                # no non-optional setting, select it right away!
                selected_bears[lang].add(bear)

    if not args.no_filter_by_capabilities:
        # capabilities satisfied till now
        satisfied_capabilities = get_bears_capabilties(selected_bears)
        remaining_capabilities = {
            lang: [cap for cap in desired_capabilities
                   if lang in satisfied_capabilities and
                   cap not in satisfied_capabilities[lang]]
            for lang in candidate_bears}

        filtered_bears = {}
        for lang, lang_bears in candidate_bears.items():
            filtered_bears[lang] = get_bears_with_given_capabilities(
                lang_bears, remaining_capabilities[lang])

        # Remove overlapping capabilty bears
        filtered_bears = remove_bears_with_conflicting_capabilties(
            filtered_bears)

        # Add to the selected_bears
        for lang, lang_bears in filtered_bears.items():
            if not selected_bears.get(lang):
                selected_bears[lang] = lang_bears
            else:
                selected_bears[lang].update(lang_bears)

    return selected_bears
示例#20
0
def filter_relevant_bears(used_languages,
                          printer,
                          arg_parser,
                          extracted_info,
                          log_printer=None):
    """
    From the bear dict, filter the bears per relevant language.

    :param used_languages:
        A list of tuples with language name as the first element
        and percentage usage as the second element; sorted by
        percentage usage.
    :param printer:
        ``ConsolePrinter`` object to be used for console interactions.
    :param arg_parser:
        ``argparse.ArgumentParser`` object containing the arguments
        passed.
    :param extracted_info:
        list of information extracted from ``InfoExtractor`` classes.
    :return:
        A dict with language name as key and bear classes as value.
    """
    args = arg_parser.parse_args() if arg_parser else None
    used_languages.append(('All', 100))

    bears_by_lang = {
        lang: set(
            inverse_dicts(*get_filtered_bears(
                [lang], log_printer, arg_parser, silent=True)).keys())
        for lang, _ in used_languages
    }

    # Each language would also have the language independent bears. We remove
    # those and put them in the "All" category.
    all_lang_bears = bears_by_lang['All']
    bears_by_lang = {
        lang: bears_by_lang[lang] - bears_by_lang['All']
        for lang, _ in used_languages
    }
    bears_by_lang['All'] = all_lang_bears

    selected_bears = {}
    candidate_bears = copy.copy(bears_by_lang)
    to_propose_bears = {}

    REQUIRED_BEAR_LIST = IMPORTANT_BEAR_LIST

    if args.green_mode:
        from coala_quickstart.Constants import (
            GREEN_MODE_COMPATIBLE_BEAR_LIST,
            GREEN_MODE_INCOMPATIBLE_BEAR_LIST,
        )
        REQUIRED_BEAR_LIST = concatenate(IMPORTANT_BEAR_LIST,
                                         GREEN_MODE_COMPATIBLE_BEAR_LIST)
        NEW_REQUIRED_BEAR_LIST = {}
        for lang in REQUIRED_BEAR_LIST:
            NEW_REQUIRED_BEAR_LIST[lang] = set()
            for bear in REQUIRED_BEAR_LIST[lang]:
                if bear not in GREEN_MODE_INCOMPATIBLE_BEAR_LIST:
                    NEW_REQUIRED_BEAR_LIST[lang].add(bear)
        REQUIRED_BEAR_LIST = NEW_REQUIRED_BEAR_LIST

    # Initialize selected_bears with REQUIRED_BEAR_LIST
    for lang, lang_bears in candidate_bears.items():
        if lang_bears and lang in REQUIRED_BEAR_LIST:
            selected_bears[lang] = set()
            for bear in lang_bears:
                if bear.__name__ in REQUIRED_BEAR_LIST[lang]:
                    selected_bears[lang].add(bear)
        if lang_bears and lang not in REQUIRED_BEAR_LIST and (
                not args.green_mode):
            selected_bears[lang] = set(lang_bears)

        candidate_bears[lang] = set([
            bear for bear in lang_bears
            if lang in selected_bears and bear not in selected_bears[lang]
        ])

    if args.green_mode:
        return selected_bears

    if not args.no_filter_by_capabilities:
        # Ask user for capablities
        user_selected_capabilities = set()
        if not args.non_interactive:
            user_selected_capabilities = ask_to_select_capabilities(
                list(ALL_CAPABILITIES), list(DEFAULT_CAPABILITIES), printer)

        desired_capabilities = (user_selected_capabilities
                                if user_selected_capabilities else
                                DEFAULT_CAPABILITIES)

        # Filter bears based on capabilities
        for lang, lang_bears in candidate_bears.items():
            # Eliminate bears which doesn't contain the desired capabilities
            capable_bears = get_bears_with_given_capabilities(
                lang_bears, desired_capabilities)
            candidate_bears[lang] = capable_bears

    lint_task_info = extracted_info.get('LintTaskInfo', [])
    project_dependency_info = extracted_info.get('ProjectDependencyInfo', [])

    # Use lint_task_info to propose bears to user.
    for lang, lang_bears in candidate_bears.items():
        matching_linter_bears = get_matching_linter_bears(
            lang_bears, lint_task_info)
        to_propose_bears[lang] = matching_linter_bears

    # Use project_dependency_info to propose bears to user.
    for lang, lang_bears in candidate_bears.items():
        matching_dep_bears = get_bears_with_matching_dependencies(
            lang_bears, project_dependency_info)
        if to_propose_bears.get(lang):
            to_propose_bears[lang].update(matching_dep_bears)
        else:
            to_propose_bears[lang] = matching_dep_bears

    for lang, lang_bears in to_propose_bears.items():
        for bear in lang_bears:
            # get the non-optional settings of the bears
            settings = bear.get_non_optional_settings()
            if settings:
                user_input_reqd = False
                for setting in settings:
                    if not is_autofill_possible(setting, lang, bear,
                                                extracted_info):
                        user_input_reqd = True
                        break

                if user_input_reqd:
                    # Ask user to activate the bear
                    if (args and not args.non_interactive
                            and prompt_to_activate(bear, printer)):
                        selected_bears[lang].add(bear)
                else:
                    # All the non-optional settings can be filled automatically
                    selected_bears[lang].add(bear)
            else:
                # no non-optional setting, select it right away!
                selected_bears[lang].add(bear)

    if not args.no_filter_by_capabilities:
        # capabilities satisfied till now
        satisfied_capabilities = get_bears_capabilities(selected_bears)
        remaining_capabilities = {
            lang: [
                cap for cap in desired_capabilities
                if lang in satisfied_capabilities
                and cap not in satisfied_capabilities[lang]
            ]
            for lang in candidate_bears
        }

        filtered_bears = {}
        for lang, lang_bears in candidate_bears.items():
            filtered_bears[lang] = get_bears_with_given_capabilities(
                lang_bears, remaining_capabilities[lang])

        # Remove overlapping capability bears
        filtered_bears = remove_bears_with_conflicting_capabilities(
            filtered_bears)

        # Add to the selected_bears
        for lang, lang_bears in filtered_bears.items():
            if not selected_bears.get(lang):
                selected_bears[lang] = lang_bears
            else:
                selected_bears[lang].update(lang_bears)

    return selected_bears