Skip to content

Commit

Permalink
Collectors: Create basic bear collector by aspect
Browse files Browse the repository at this point in the history
Enable coala to collect bears based on aspects configuration.
Currently, the algorithm to collects is very simple, iterate
over all bears in coala and pick the first bear that capable to
handle an aspect and have compatible language. Improvement will
be implemented in future patch.

Closes #4531
  • Loading branch information
adhikasp committed Jul 24, 2017
1 parent 55c4dce commit 4f8ee34
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 9 deletions.
27 changes: 27 additions & 0 deletions coalib/collecting/Collectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,33 @@ def filter_section_bears_by_languages(bears, languages):
return new_bears


def collect_bears_by_aspects(aspects, kinds):
"""
Collect bear based on aspects.
Return a list of bears that have capability to analyze all aspects from
given AspectList requirement.
:param aspects: An AspectList that need to be covered.
:param kinds: List of bear kinds to be collected.
:return: Tuple of list of bear classes based on kind. The lists are
in the same order as kinds.
"""
all_bears = get_all_bears()
bears_found = tuple([] for i in range(len(kinds)))
for aspect in aspects.get_leaf_aspects():
for bear in all_bears:
if (aspect in bear.aspects['detect'] or
aspect in bear.aspects['fix']):
index = kinds.index(_get_kind(bear))
# Avoid duplicate
if bear not in bears_found[index]:
bears_found[index].append(bear)
break

return bears_found


def filter_capabilities_by_languages(bears, languages):
"""
Filters the bears capabilities by languages.
Expand Down
7 changes: 6 additions & 1 deletion coalib/settings/ConfigurationGathering.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,13 @@ def aspectize_sections(sections):
:param sections: List of section that potentially contain aspects setting.
:return: The new sections.
"""
for _, section in sections.items():
for section_name, section in sections.items():
section.aspects = extract_aspects_from_section(section)
if section.aspects is not None and len(section.get('bears')):
logging.warning("'aspects' and 'bears' configuration is detected "
"in section '{}'. Aspect-based configuration will "
'takes priority and will overwrite any '
'explicitly listed bears'.format(section_name))
return sections


Expand Down
21 changes: 14 additions & 7 deletions coalib/settings/SectionFilling.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

from coalib.bears.BEAR_KIND import BEAR_KIND
from coalib.collecting import Dependencies
from coalib.collecting.Collectors import collect_bears
from coalib.collecting.Collectors import (
collect_bears, collect_bears_by_aspects)
from coalib.settings.Setting import Setting


Expand Down Expand Up @@ -83,12 +84,18 @@ def fill_settings(sections,

for section_name, section in sections.items():
bear_dirs = section.bear_dirs()
bears = list(section.get('bears', ''))
section_local_bears, section_global_bears = collect_bears(
bear_dirs,
bears,
[BEAR_KIND.LOCAL, BEAR_KIND.GLOBAL],
log_printer)
if getattr(section, 'aspects', None):
section_local_bears, section_global_bears = (
collect_bears_by_aspects(
section.aspects,
[BEAR_KIND.LOCAL, BEAR_KIND.GLOBAL]))
else:
bears = list(section.get('bears', ''))
section_local_bears, section_global_bears = collect_bears(
bear_dirs,
bears,
[BEAR_KIND.LOCAL, BEAR_KIND.GLOBAL],
log_printer)
section_local_bears = Dependencies.resolve(section_local_bears)
section_global_bears = Dependencies.resolve(section_global_bears)
all_bears = copy.deepcopy(section_local_bears)
Expand Down
15 changes: 14 additions & 1 deletion tests/collecting/CollectorsTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@

from pyprint.ConsolePrinter import ConsolePrinter

from coalib.bearlib.aspects import AspectList, get as get_aspect
from coalib.bears.BEAR_KIND import BEAR_KIND
from coalib.bears.Bear import Bear
from coalib.collecting.Collectors import (
collect_all_bears_from_sections, collect_bears, collect_dirs, collect_files,
collect_registered_bears_dirs, filter_section_bears_by_languages,
get_all_bears, get_all_bears_names)
get_all_bears, get_all_bears_names, collect_bears_by_aspects)
from coalib.output.printers.LogPrinter import LogPrinter
from coalib.output.printers.ListLogPrinter import ListLogPrinter
from coalib.settings.Section import Section
Expand Down Expand Up @@ -275,6 +277,17 @@ def test_all_bears_from_sections(self):
self.assertEqual(len(local_bears['test_section']), 2)
self.assertEqual(len(global_bears['test_section']), 2)

def test_aspect_bear(self):
with bear_test_module():
aspects = AspectList([get_aspect('unusedvariable')('py')])
local_bears, global_bears = collect_bears_by_aspects(
aspects,
[BEAR_KIND.LOCAL, BEAR_KIND.GLOBAL])

self.assertEqual(len(global_bears), 0)
self.assertEqual(len(local_bears), 1)
self.assertIs(local_bears[0].name, 'AspectTestBear')


class CollectorsTests(unittest.TestCase):

Expand Down

0 comments on commit 4f8ee34

Please sign in to comment.